CVE-2026-54659

CVE-2026-54659 is a medium-severity path traversal vulnerability in pagy (rubygems), affecting versions >= 43.0.0, < 43.5.6. It is fixed in 43.5.6.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Pagy I18n locale option is not validated before being used in a file path

Pagy::I18n.locale= did not validate its argument before using it as a
path component to load the matching dictionary file (<locale>.yml). An
application that assigns untrusted input to the locale, e.g. the common
pattern Pagy::I18n.locale = params[:locale], let that input influence
which file Pagy attempted to load.

Details

The setter stored the value as-is, and the loader joined it into a path
and read it:

# gem/lib/pagy/modules/i18n/i18n.rb
def locale=(value)
  Thread.current[:pagy_locale] = value.to_s
end

# ...later, when translating:
path = pathnames.reverse.map { |p| p.join("#{locale}.yml") }.find(&:exist?)
dictionary = YAML.load_file(path)[locale]

Because the locale was used verbatim, a value such as an absolute path or
a ../-style string redirected the lookup outside the locales directory.
Pagy's subsequent structural check (dictionary['pagy']['p11n'])
prevents the file's contents from being returned, so this is not a
direct file read.

Fixed in 43.5.6 by constraining the locale to a BCP 47 shape before use:

LOCALE_PATTERN = /\A[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*\z/

def locale=(value)
  Thread.current[:pagy_locale] = value.to_s[LOCALE_PATTERN]
end

Any non-matching value (including nil) resolves to the default locale
and never reaches the file lookup.

PoC

In an application that sets Pagy::I18n.locale = params[:locale], the
loader appends .yml and reads <locale>.yml, so the request param
controls the target path. For example, pointing it at the app's
config/database.yml:

  1. Send a request with ?locale=../../../config/database (adjust the
    number of ../ to reach the app root from the gem's locales/
    directory).
  2. Pagy calls YAML.load_file on the resulting …/config/database.yml.
  3. The outcome differs by whether that .yml exists, is readable, parses
    as YAML, and has Pagy's expected structure, an existing, readable
    config/database.yml raises a different error than a non-existent
    path (which silently falls back to the default locale). This yields a
    file-existence / readability oracle for .yml paths, and the targeted
    file is read into the process during the attempt.

Impact

Information disclosure (CWE-22 / CWE-200): a file-existence / readability
oracle for .yml paths on the host, plus a server-side read of
attacker-chosen files into the process. The file contents are not
returned in the response.

Only applications that pass unsanitized end-user input into
Pagy::I18n.locale= are affected. Applications that set the locale from
trusted values are not affected.

Patched: pagy 43.5.6.
Workaround (if you cannot upgrade): validate the locale before
assigning it, e.g.
Pagy::I18n.locale = params[:locale].to_s[/\A[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*\z/],
or restrict it to your known set of locales.

Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files. Typical impact: unauthorized file read or write outside the intended directory.

Affected versions

pagy (>= 43.0.0, < 43.5.6)

Security releases

pagy → 43.5.6 (rubygems)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade pagy to 43.5.6 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is CVE-2026-54659? CVE-2026-54659 is a medium-severity path traversal vulnerability in pagy (rubygems), affecting versions >= 43.0.0, < 43.5.6. It is fixed in 43.5.6. Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files.
  2. Which versions of pagy are affected by CVE-2026-54659? pagy (rubygems) versions >= 43.0.0, < 43.5.6 is affected.
  3. Is there a fix for CVE-2026-54659? Yes. CVE-2026-54659 is fixed in 43.5.6. Upgrade to this version or later.
  4. Is CVE-2026-54659 exploitable, and should I be worried? Whether CVE-2026-54659 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether CVE-2026-54659 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix CVE-2026-54659? Upgrade pagy to 43.5.6 or later.

Stop the waste.
Protect your environment with Kodem.