CVE-2026-118258
i18next-http-backend: Query-parameter injection through & and = in lng when loadPath/addPath puts {{lng}} in the query string
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
3.7
i18next-http-backend: Query-parameter injection through & and = in lng when loadPath/addPath puts {{lng}} in the query string
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
- Record
CVE-2026-118258- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-74
- Updated
- 2026-11-03
EUVDEUVD-2026-112360
3.7
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
- Record
EUVD-2026-112360- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Updated
- 2026-11-03
GitHub AdvisoriesGHSA-3cmx-xjww-583x
3.7
i18next-http-backend: Query-parameter injection through & and = in lng when loadPath/addPath puts {{lng}} in the query string
Summary
The URL-segment check added for GHSA-q89c-q3h5-w34g blocks ?, #, %, :, / and @ in lng, but not & or =, and the checked value is inserted into the URL without encoding. The README documents a multiload loadPath of the form /locales/resources.json?lng=de+en&ns=ns1+ns2. With a template like that, an attacker who controls the language value can add or override query parameters on the request the backend sends. By default the language comes from ?lng=, a cookie or Accept-Language. This is the "query-string injection" impact described in GHSA-q89c; only the ? form was closed.
Server side (Express + i18next-http-middleware, default options), GET /?lng=de%26ns%3Dprivate%26admin%3Dtrue makes the application request …?lng=de&ns=private&admin=true&ns=common from its own translations API.
Details
The checks are in lib/utils.js. The base check (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L26-L44) rejects:
- empty or >128-character values and prototype keys;
..and\;/[?#%:\s]/;- control characters.
isSafeLangUrlSegment (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L51-L55) adds only / and @. Neither function rejects & or =.
if (/[?#%:\s]/.test(v)) return false // utils.js L40, no & or =
interpolateUrl then splits on +, checks each segment, and joins the raw segments into the template, with no encoding (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L159-L184, return at L174).
Call sites:
_readAnybuilds the load URL withinterpolateUrl(resolvedLoadPath, { lng: languages.join('+'), ns: … }): https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/index.js#L64createbuilds the missing-key URL withinterpolateUrl(addPath, { lng, ns }): https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/index.js#L133
The README documents the query-shaped URL for multiloading (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/README.md?plain=1#L130). The language value is attacker-controlled in normal setups, as GHSA-q89c itself says: detectors read ?lng=, cookies, localStorage and request headers. i18next-http-middleware's LanguageDetector does the same on the server.
Where ? is placed in the template determines which characters are structural. The fix treated only the path position. In a query position, & and = are the separators, so they must be rejected or encoded too.
Suggested fix. Reject & and = (and ;) in both lng and ns; no BCP-47 language code or usable i18next namespace contains them. Alternatively, encodeURIComponent each +-joined segment when the placeholder appears after ? in the template.
Proof of concept
How to run (Node 18+; everything runs on 127.0.0.1, with a fake translations API and an Express app):
mkdir i18next-poc && cd i18next-pocnpm init -ynpm i [email protected] [email protected] [email protected] [email protected]- Save the script below as
poc.mjs node poc.mjs
// i18next-http-backend 4.0.3: '&' and '=' in lng pass isSafeLangUrlSegment, so a loadPath that puts
// {{lng}} in the query string (README multiload shape) gets extra parameters.
// Everything runs on 127.0.0.1: a fake translations API and an Express app.
import http from 'node:http'
import express from 'express'
import i18next from 'i18next'
import Backend from 'i18next-http-backend'
import middleware from 'i18next-http-middleware'
const seen = []
const api = http.createServer((req, res) => {
seen.push(req.url)
res.setHeader('content-type', 'application/json')
res.end('{"hello":"hi"}')
})
await new Promise((r) => api.listen(0, '127.0.0.1', r))
const loadPath = `http://127.0.0.1:${api.address().port}/locales/resources.json?lng={{lng}}&ns={{ns}}`
const wait = () => new Promise((r) => setTimeout(r, 200))
// 1) Direct: lng values passed to i18next…
- Record
GHSA-3cmx-xjww-583x- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-74
- Updated
- 2026-11-02
NVD
3.7
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
- Record
CVE-2026-118258- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-74
- Updated
- 2026-11-03
OSV
3.7
i18next-http-backend: Query-parameter injection through & and = in lng when loadPath/addPath puts {{lng}} in the query string
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
- Record
CVE-2026-118258- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-74
- Updated
- 2026-11-07
OSVGHSA-3cmx-xjww-583x
3.7
i18next-http-backend: Query-parameter injection through & and = in lng when loadPath/addPath puts {{lng}} in the query string
Summary
The URL-segment check added for GHSA-q89c-q3h5-w34g blocks ?, #, %, :, / and @ in lng, but not & or =, and the checked value is inserted into the URL without encoding. The README documents a multiload loadPath of the form /locales/resources.json?lng=de+en&ns=ns1+ns2. With a template like that, an attacker who controls the language value can add or override query parameters on the request the backend sends. By default the language comes from ?lng=, a cookie or Accept-Language. This is the "query-string injection" impact described in GHSA-q89c; only the ? form was closed.
Server side (Express + i18next-http-middleware, default options), GET /?lng=de%26ns%3Dprivate%26admin%3Dtrue makes the application request …?lng=de&ns=private&admin=true&ns=common from its own translations API.
Details
The checks are in lib/utils.js. The base check (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L26-L44) rejects:
- empty or >128-character values and prototype keys;
..and\;/[?#%:\s]/;- control characters.
isSafeLangUrlSegment (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L51-L55) adds only / and @. Neither function rejects & or =.
if (/[?#%:\s]/.test(v)) return false // utils.js L40, no & or =
interpolateUrl then splits on +, checks each segment, and joins the raw segments into the template, with no encoding (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/utils.js#L159-L184, return at L174).
Call sites:
_readAnybuilds the load URL withinterpolateUrl(resolvedLoadPath, { lng: languages.join('+'), ns: … }): https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/index.js#L64createbuilds the missing-key URL withinterpolateUrl(addPath, { lng, ns }): https://github.com/i18next/i18next-http-backend/blob/v4.0.3/lib/index.js#L133
The README documents the query-shaped URL for multiloading (https://github.com/i18next/i18next-http-backend/blob/v4.0.3/README.md?plain=1#L130). The language value is attacker-controlled in normal setups, as GHSA-q89c itself says: detectors read ?lng=, cookies, localStorage and request headers. i18next-http-middleware's LanguageDetector does the same on the server.
Where ? is placed in the template determines which characters are structural. The fix treated only the path position. In a query position, & and = are the separators, so they must be rejected or encoded too.
Suggested fix. Reject & and = (and ;) in both lng and ns; no BCP-47 language code or usable i18next namespace contains them. Alternatively, encodeURIComponent each +-joined segment when the placeholder appears after ? in the template.
Proof of concept
How to run (Node 18+; everything runs on 127.0.0.1, with a fake translations API and an Express app):
mkdir i18next-poc && cd i18next-pocnpm init -ynpm i [email protected] [email protected] [email protected] [email protected]- Save the script below as
poc.mjs node poc.mjs
// i18next-http-backend 4.0.3: '&' and '=' in lng pass isSafeLangUrlSegment, so a loadPath that puts
// {{lng}} in the query string (README multiload shape) gets extra parameters.
// Everything runs on 127.0.0.1: a fake translations API and an Express app.
import http from 'node:http'
import express from 'express'
import i18next from 'i18next'
import Backend from 'i18next-http-backend'
import middleware from 'i18next-http-middleware'
const seen = []
const api = http.createServer((req, res) => {
seen.push(req.url)
res.setHeader('content-type', 'application/json')
res.end('{"hello":"hi"}')
})
await new Promise((r) => api.listen(0, '127.0.0.1', r))
const loadPath = `http://127.0.0.1:${api.address().port}/locales/resources.json?lng={{lng}}&ns={{ns}}`
const wait = () => new Promise((r) => setTimeout(r, 200))
// 1) Direct: lng values passed to i18next…
- Record
GHSA-3cmx-xjww-583x- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-74
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-118258
3.7
i18next-http-backend is a backend layer for i18next that loads translation resources in Node.js, browsers, and Deno. Prior to 4.0.4, interpolateUrl inserts unencoded language and namespace values into loadPath or addPath templates without rejecting ampersand (&), equals (=), or semicolon (;) query separators. When a template places lng or ns in the query string and an attacker controls that value, the attacker can add or override parameters on browser or server-side translation requests, potentially exposing other namespaces or tenants or changing backend behavior through the application's network position and credentials. This vulnerability is the result of an incomplete fix for CVE-2026-41691. This issue is fixed in version 4.0.4.
- Record
UBUNTU-CVE-2026-118258- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Updated
- 2026-11-05
OSVCLSA-2026-1793698178 No score
TuxCare security update for i18next-http-backend (1 CVE)
TuxCare rebuilt i18next-http-backend to address 1 CVE. Fixed in 2.5.2-tuxcare.3.
- Record
CLSA-2026-1793698178- Updated
- 2026-11-03
OSVCLSA-2026-1793699861 No score
TuxCare security update for i18next-http-backend (1 CVE)
TuxCare rebuilt i18next-http-backend to address 1 CVE. Fixed in 1.4.4-tuxcare.3.
- Record
CLSA-2026-1793699861- Updated
- 2026-11-03
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
i18next-http-backendnpm |
before 4.0.4 | 4.0.4 |
i18next-http-backendTuxCare:npm |
2.5.2-tuxcare.0 up to 2.5.2-tuxcare.3, plus listed versions 2.5.22.5.2-tuxcare.12.5.2-tuxcare.2 |
2.5.2-tuxcare.3 |
i18next-http-backendTuxCare:npm |
1.4.4-tuxcare.0 up to 1.4.4-tuxcare.3, plus listed versions 1.4.41.4.4-tuxcare.11.4.4-tuxcare.2 |
1.4.4-tuxcare.3 |
node-i18next-http-backendUbuntu:22.04:LTS |
All versions, plus listed versions 1.0.21+dfsg-11.3.1+dfsg-21.3.1+dfsg-31.3.1+dfsg-41.3.2+dfsg-1 |
None known |
node-i18next-http-backendUbuntu:24.04:LTS |
All versions, plus listed versions 2.1.1-12.4.1+ds-22.4.1+ds-2build2 |
None known |
node-i18next-http-backendUbuntu:26.10 |
All versions, plus listed versions 2.4.1+ds-2build2 |
None known |
node-i18next-http-backendUbuntu:26.04:LTS |
All versions, plus listed versions 2.4.1+ds-2build2 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | EUVD, NVD | |
| references | CVE List | |
| affected, aliases | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-118258 is a low vulnerability (CVSS 3.7) in I18next I18next-http-backend, published October 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.28%, the 20th percentile. Fixed in i18next-http-backend 4.0.4.
References
github.com/i18next/i18next-http-backend/security/advisories/GHSA-3cmx-xjww-583x
github.com/i18next/i18next-http-backend/commit/b0eef9efd425055c554787cef7f878de33bbf510
github.com/i18next/i18next-http-backend/releases/tag/v4.0.4
github.com/advisories/GHSA-3cmx-xjww-583x
github.com/CVEProject/cvelistV5/tree/main/cves/2026/118xxx/CVE-2026-118258.json
nvd.nist.gov/vuln/detail/CVE-2026-118258
github.com/i18next/i18next-http-backend
ubuntu.com/security/CVE-2026-118258
cve.org/CVERecord?id=CVE-2026-118258
Left out here: the rest of 2 source descriptions. The JSON record has them.