Skip to content

chore(deps): update dependency i18next-http-backend to v3.0.5 [security]#21390

Draft
renovate[bot] wants to merge 1 commit intodevelopfrom
renovate/npm-i18next-http-backend-vulnerability
Draft

chore(deps): update dependency i18next-http-backend to v3.0.5 [security]#21390
renovate[bot] wants to merge 1 commit intodevelopfrom
renovate/npm-i18next-http-backend-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented Apr 22, 2026

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
i18next-http-backend 3.0.23.0.5 age adoption passing confidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


i18next-http-backend has Path Traversal & URL Injection via Unsanitised lng/ns

GHSA-q89c-q3h5-w34g

More information

Details

Summary

Versions of i18next-http-backend prior to 3.0.5 interpolate the lng and ns values directly into the configured loadPath / addPath URL template without any encoding, validation, or path sanitisation. When an application exposes the language-code selection to user-controlled input (the default — i18next-browser-languagedetector reads ?lng= query params, cookies, localStorage, and request headers), an attacker can inject characters that change the structure of the outgoing request URL.

Affected call sites:

  • _readAnylib/index.js:64: interpolate(resolvedLoadPath, { lng: languages.join('+'), ns: namespaces.join('+') })
  • createlib/index.js:123 (pre-patch): interpolate(addPath, { lng, ns: namespace })

The helper interpolate (lib/utils.js) previously returned the raw value with no encoding. In contrast, addQueryString already correctly uses encodeURIComponent for each query-string param — only the URL-path substitution was unprotected.

Impact

An attacker who can influence the resolved lng or ns value can alter the URL in several ways:

  • Path traversallng = '../../config' turns /locales//.json into /locales/../../config/translation.json. On a misconfigured web server, this can cause the request to target a different resource than intended; in SSR pipelines that use file:// or similar schemes for loadPath, it can read arbitrary files from the host filesystem.
  • Query-string injectionlng = 'en?admin=true' turns /locales//.json into /locales/en?admin=true/translation.json. Some server frameworks parse the query portion with higher priority than the path and branch on attacker-controlled flags.
  • Fragment truncationlng = 'en#anything' silently discards the rest of the path in browser fetches (client cannot see the final URL).
  • URL-encoded bypasseslng = 'en%2F..', after server-side URL decoding, resolves to en/.. — the attacker bypasses the absence of a literal / in their input.

The practical worst case is SSRF when loadPath is an internal or file-scheme URL, and path-based authorisation bypass against servers that segment access by URL prefix.

Also fixed in 3.0.5
  • Per-instance omitFetchOptions. A module-level boolean in lib/request.js was flipped to true the first time any backend instance hit a "not implemented" fetch error. Once flipped, all subsequent requests from all backend instances in the same module silently stripped every user-configured fetch option — including security-relevant credentials, mode, and cache. One misbehaving instance (for example during SSR hydration or in React Native) permanently removed these protections process-wide. 3.0.5 scopes the flag to the backend's options object (options._omitFetchOptions) so one instance's fallback cannot pollute siblings.
  • Log forging via control characters in lng/ns. Error callbacks embedded the raw lng/ns/URL in the message string. Crafted CR/LF values could inject fake log lines into file-backed log aggregators (CWE-117). 3.0.5 strips C0/C1 control chars before concatenation.
  • Basic-auth credentials leaked into error callbacks. If loadPath contained a user:password@host authority, the full URL (including the credentials) ended up in the error message strings returned to the caller. 3.0.5 redacts user:password@ before logging.
  • Prototype-pollution amplification via for...in. addQueryString and the XHR customHeaders loop used for...in which walks the prototype chain. Polluted Object.prototype entries could leak into URL query parameters and request headers. 3.0.5 uses Object.keys and an explicit prototype-key guard.
Affected versions

All versions of i18next-http-backend prior to 3.0.5.

Patch

Fixed in 3.0.5. Summary of the hardening:

  1. New utils.interpolateUrl (used by _readAny and create) returns null if any substitution fails the URL-segment safety check (blocks .., /, \, ?, #, %, @, whitespace, control chars, prototype keys, and values > 128 chars). Multi-language joins (en+de) are validated per-segment. The call sites now refuse to issue a request when the check fails and call back with a clear error.
  2. omitFetchOptions is stored per-instance on options._omitFetchOptions.
  3. Error-callback messages sanitise strings and redact URL credentials.
  4. for...in over untrusted objects replaced with Object.keys + prototype-key guard.
Workarounds

No workaround short of upgrading. If you cannot upgrade immediately, sanitise lng / ns yourself before they reach i18next (strip .., /, \, ?, #, %, whitespace, and control characters; cap the length).

Credits

Discovered via an internal security audit of the i18next ecosystem.

Severity

  • CVSS Score: 6.5 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

i18next/i18next-http-backend (i18next-http-backend)

v3.0.5

Compare Source

Security release — all issues found via an internal audit. See published advisory GHSA-q89c-q3h5-w34g.

  • security: refuse to build request URLs when lng or ns values contain path-traversal, URL-structure (?, #, %, @, whitespace), path separators, control characters, prototype keys, or exceed 128 chars. Prevents path traversal / SSRF / URL injection via attacker-controlled language-code values. isSafeUrlSegment is permissive for legitimate i18next language codes (any BCP-47-like shape, underscores, hyphens, dots, +-joined multi-language requests) (GHSA-q89c-q3h5-w34g)
  • security: per-instance omitFetchOptions — the fetch-options-stripping fallback is now scoped to a single backend instance via options._omitFetchOptions instead of a module-level boolean. One instance hitting a "not implemented" fetch error no longer permanently strips requestOptions (including credentials, mode, cache) from every other backend instance in the same process
  • security: strip CR/LF/NUL and other C0/C1 control characters from lng/ns / URL values before they appear in error-callback strings (CWE-117 log forging)
  • security: redact user:password credentials from URLs before including them in error-callback strings — prevents leaking basic-auth credentials embedded in loadPath / addPath
  • security: iterate own enumerable keys only (Object.keys + prototype-key guard) in addQueryString and in the customHeaders loop in XHR mode — prevents prototype-pollution amplification into the URL and request headers
  • chore: ignore .env* and *.pem/*.key files in .gitignore

v3.0.4

Compare Source

  • use own interpolation function for loadPath and addPath instead of relying on i18next's interpolator i18next#2420 — this means only {{lng}} and {{ns}} placeholders are supported; custom interpolation prefix/suffix from i18next config no longer applies to backend paths

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Never, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.
Managed by the SAP Open Source Program Office. For questions/issues please raise an issue in the renovate-controller repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants