CVE-2026-41693: i18next-fs-backend Path Traversal Vulnerability

HIGH
Advisory Identifier: GHSA-8847-338w-5hcj
CVSS 8.2
CWE-73 CWE-22
Published
Advisory Summary

CVE-2026-41693 is a HIGH (CVSS 8.2) path traversal vulnerability (CWE-73: External Control of File Name or Path) affecting i18next-fs-backend libraries in the npm ecosystem. The issue involves path traversal via unsanitised lng/ns allows arbitrary file read/overwrite. Remediation is available by upgrading affected packages to version 2.6.4.

CVE-2026-41693 at a Glance

CVE Identifier CVE-2026-41693
GHSA Identifier GHSA-8847-338w-5hcj
Severity HIGH
CVSS v3.1 Base Score 8.2
CWE Classification CWE-73: External Control of File Name or Path
Affected Product i18next-fs-backend
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 8.2

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity Low (I:L)
Availability None (A:N)

How to Fix CVE-2026-41693

To remediate this vulnerability, upgrade all affected i18next-fs-backend dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

i18next-fs-backend fixed: 2.6.4
npm install i18next-fs-backend@2.6.4
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls i18next-fs-backend

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-41693, inspect your project dependencies using npm:

npm ls i18next-fs-backend

Analyze the terminal output to locate any version of i18next-fs-backend in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.6.4), your application is affected.

Note: The npm ls i18next-fs-backend command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-73: External Control of File Name or Path, where the product allows user input to control or influence paths or file names that are used in filesystem operations. In i18next-fs-backend, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Versions of `i18next-fs-backend` prior to 2.6.4 interpolate the caller-supplied `lng` and `ns` values directly into the configured `loadPath` and `addPath` templates with no path-component validation and no sanitisation. When an application exposes the resolved language code to user-controlled input (`?lng=` query parameter, cookie, request header), a crafted value can break out of the intended locale directory. Affected call sites in `lib/index.js`: - `read` (line 38 pre-patch): `const filename = interpolate(loadPath, { lng: language, ns: namespace })` - `removeFile` (line 101 pre-patch): same pattern against `addPath` - `writeFile` (line 127 pre-patch): same pattern against `addPath` for queued missing-key writes The helper `interpolate` in `lib/utils.js` substitutes raw values with no encoding — unlike the `addQueryString` helper in `i18next-http-backend`, there is no equivalent safety for path interpolation. ### Impact - **Arbitrary file read.** With a `loadPath` like `/locales/{{lng}}/{{ns}}.json`, an attacker-controlled `lng = '../../etc'` (and matching `ns`) causes the backend to read a file outside the locale directory. For parsers that tolerate arbitrary content (YAML's freeform text), the file contents surface as a translation resource. - **Arbitrary file overwrite.** `addPath` is interpolated the same way for missing-key writes (the `create()` code path and the debounced writer in `writeFile`). A traversing `lng`/`ns` combination can cause the process to write JSON structures to an unintended filesystem location, potentially overwriting application files if the process user has write access. - **Chain with `.js`/`.ts` eval.** `i18next-fs-backend` supports loading `.js` and `.ts` locale files by `eval`-ing their content (intentional feature, documented as requiring trusted sources). Combining traversal with that path — for example `lng = '../../../app/config'` against `loadPath: '/locales/{{lng}}/{{ns}}.js'` — would cause the backend to **execute** a server-side file as JavaScript, exfiltrating whatever it can touch (`process.env`, connected services). Exploitation requires the application to pass an untrusted `lng`/`ns` value through to `i18next.t()` without its own validation. Many i18next setups do exactly this via `i18next-browser-languagedetector` (query string / cookie detection). ### Affected versions All versions of `i18next-fs-backend` prior to **2.6.4**. ### Patch Fixed in **2.6.4**. `lib/utils.js` now exports: - `isSafePathSegment(v)` — returns `true` only if `v` is a non-empty string of ≤ 128 chars that does not contain `..`, `/`, `\`, control characters, or a prototype key (`__proto__`, `constructor`, `prototype`). Legitimate i18next language-code shapes (BCP-47, `en_US`, `zh-Hant-HK`, `pirate-speak`, `my-custom.ns`, `+`-joined multi-language values) all pass. - `interpolatePath(template, data)` — substitutes variables like the existing `interpolate` but refuses the whole result if any segment fails `isSafePathSegment`. Callers bail out with an error (`read`) or silently drop the queued write (`writeFile`, `removeFile`). The `.js` / `.ts` `eval` behaviour is intentionally retained — dynamic expressions in locale files are a documented feature of this backend, and safe replacements like dynamic `import()` are async-only and incompatible with this backend's sync-capable code path. The README has a new "Security considerations" section that spells out the trust model: `.js`/`.ts` locale files must be treated as code. ### Workarounds No workaround short of upgrading. If you cannot upgrade immediately, sanitise `lng` / `ns` at your application boundary before passing them to i18next — reject values containing `..`, `/`, `\`, control characters, and cap the length. ### Credits Discovered via an internal security audit of the i18next ecosystem.

CVE-2026-41693 Affected i18next-fs-backend Versions

1 component(s)
Fixed Versions:
2.6.4
Product / Package Ecosystem Affected Versions Fixed Version
i18next-fs-backend
npm
< 2.6.4
2.6.4

References

Frequently Asked Questions

What is CVE-2026-41693?
CVE-2026-41693 is a security vulnerability in i18next-fs-backend involving Path traversal via unsanitised lng/ns allows arbitrary file read/overwrite under CWE-73: External Control of File Name or Path.
Which i18next-fs-backend versions are affected?
Affected versions include releases prior to 2.6.4 across affected packages: i18next-fs-backend.
What version fixes CVE-2026-41693?
Upgrading to 2.6.4 (or the latest patched release for your respective branch) resolves the vulnerability.
Is i18next-fs-backend affected?
Yes, i18next-fs-backend is affected in releases prior to 2.6.4. Upgrade your dependency to 2.6.4 or later.
What is the CVSS score of CVE-2026-41693?
CVE-2026-41693 has a CVSS v3.1 base score of 8.2 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N.
What CWE is associated with CVE-2026-41693?
CVE-2026-41693 is classified under CWE-73: External Control of File Name or Path (The product allows user input to control or influence paths or file names that are used in filesystem operations.).
How can I check npm dependencies for CVE-2026-41693?
Run the dependency tree command: 'npm ls i18next-fs-backend'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-8847-338w-5hcj",
  "modified" : "2026-05-13T13:30:00Z",
  "published" : "2026-04-22T17:43:14Z",
  "aliases" : [ "CVE-2026-41693" ],
  "summary" : "i18next-fs-backend: Path traversal via unsanitised lng/ns allows arbitrary file read/overwrite",
  "details" : "### Summary\n\nVersions of `i18next-fs-backend` prior to 2.6.4 interpolate the caller-supplied `lng` and `ns` values directly into the configured `loadPath` and `addPath` templates with no path-component validation and no sanitisation. When an application exposes the resolved language code to user-controlled input (`?lng=` query parameter, cookie, request header), a crafted value can break out of the intended locale directory.\n\nAffected call sites in `lib/index.js`:\n\n- `read` (line 38 pre-patch): `const filename = interpolate(loadPath, { lng: language, ns: namespace })`\n- `removeFile` (line 101 pre-patch): same pattern against `addPath`\n- `writeFile` (line 127 pre-patch): same pattern against `addPath` for queued missing-key writes\n\nThe helper `interpolate` in `lib/utils.js` substitutes raw values with no encoding — unlike the `addQueryString` helper in `i18next-http-backend`, there is no equivalent safety for path interpolation.\n\n### Impact\n\n- **Arbitrary file read.** With a `loadPath` like `/locales/{{lng}}/{{ns}}.json`, an attacker-controlled `lng = '../../etc'` (and matching `ns`) causes the backend to read a file outside the locale directory. For parsers that tolerate arbitrary content (YAML's freeform text), the file contents surface as a translation resource.\n- **Arbitrary file overwrite.** `addPath` is interpolated the same way for missing-key writes (the `create()` code path and the debounced writer in `writeFile`). A traversing `lng`/`ns` combination can cause the process to write JSON structures to an unintended filesystem location, potentially overwriting application files if the process user has write access.\n- **Chain with `.js`/`.ts` eval.** `i18next-fs-backend` supports loading `.js` and `.ts` locale files by `eval`-ing their content (intentional feature, documented as requiring trusted sources). Combining traversal with that path — for example `lng = '../../../app/config'` against `loadPath: '/locales/{{lng}}/{{ns}}.js'` — would cause the backend to **execute** a server-side file as JavaScript, exfiltrating whatever it can touch (`process.env`, connected services).\n\nExploitation requires the application to pass an untrusted `lng`/`ns` value through to `i18next.t()` without its own validation. Many i18next setups do exactly this via `i18next-browser-languagedetector` (query string / cookie detection).\n\n### Affected versions\n\nAll versions of `i18next-fs-backend` prior to **2.6.4**.\n\n### Patch\n\nFixed in **2.6.4**. `lib/utils.js` now exports:\n\n- `isSafePathSegment(v)` — returns `true` only if `v` is a non-empty string of ≤ 128 chars that does not contain `..`, `/`, `\\`, control characters, or a prototype key (`__proto__`, `constructor`, `prototype`). Legitimate i18next language-code shapes (BCP-47, `en_US`, `zh-Hant-HK`, `pirate-speak`, `my-custom.ns`, `+`-joined multi-language values) all pass.\n- `interpolatePath(template, data)` — substitutes variables like the existing `interpolate` but refuses the whole result if any segment fails `isSafePathSegment`. Callers bail out with an error (`read`) or silently drop the queued write (`writeFile`, `removeFile`).\n\nThe `.js` / `.ts` `eval` behaviour is intentionally retained — dynamic expressions in locale files are a documented feature of this backend, and safe replacements like dynamic `import()` are async-only and incompatible with this backend's sync-capable code path. The README has a new \"Security considerations\" section that spells out the trust model: `.js`/`.ts` locale files must be treated as code.\n\n### Workarounds\n\nNo workaround short of upgrading. If you cannot upgrade immediately, sanitise `lng` / `ns` at your application boundary before passing them to i18next — reject values containing `..`, `/`, `\\`, control characters, and cap the length.\n\n### Credits\n\nDiscovered via an internal security audit of the i18next ecosystem.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "i18next-fs-backend"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "2.6.4"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/i18next/i18next-fs-backend/security/advisories/GHSA-8847-338w-5hcj"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-41693"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/i18next/i18next-fs-backend"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-22", "CWE-73" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-22T17:43:14Z",
    "nvd_published_at" : "2026-05-08T16:16:11Z"
  }
}