VNX-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Detects Node's lenient HTTP parser switched on (insecureHTTPParser: true, --insecure-http-parser) and a message given both Transfer-Encoding and Content-Length in the same branch, the framing ambiguity behind request smuggling.
| Field | Value |
|---|---|
| Rule ID | VNX-444 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-444 |
| CAPEC | CAPEC-33 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | http-smuggling cwe-444 |
| Source | internal/sast/rules/vnx-444.rego |
Overview
VNX-444 maps to CWE-444: Inconsistent Interpretation of HTTP Requests (‘HTTP Request/Response Smuggling’). When a front-end proxy and a back-end server disagree about where one request ends, an attacker can hide a second request inside the first and have it processed with someone else’s connection.
The rule reports two code shapes that create that disagreement:
- Lenient parsing.
insecureHTTPParser: trueinhttp/httpsserver or request options, or--insecure-http-parserin a script orNODE_OPTIONS. - Two framing headers.
Transfer-EncodingandContent-Lengthboth set (setHeader/putheader/header calls, header-object keys, index assignments) within five lines of each other in the same branch, or a raw HTTP string carrying both. The finding is on theTransfer-Encodingline.
Not reported: insecureHTTPParser: false, Transfer-Encoding set after removing Content-Length, the two headers set in alternative branches (if length: ... else: chunked, or a branch that returns before the other header is set), code that reads or compares the headers, comments and prose strings.
What Gets Flagged
// FLAGGED: lenient parser
const server = http.createServer({ insecureHTTPParser: true }, app);
// FLAGGED: both framing headers on one response
res.setHeader('Content-Length', body.length);
res.setHeader('Transfer-Encoding', 'chunked');
# NOT FLAGGED: alternatives, never both
if length:
headers["Content-Length"] = str(length)
else:
headers["Transfer-Encoding"] = "chunked"
Remediation
- Remove
insecureHTTPParserand--insecure-http-parser; fix the client that needed them. - Send exactly one framing header:
Content-Lengthwhen the size is known, chunked otherwise. - Reject inbound requests that carry both headers.
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-444
// nosec vnx-444
Or record an ignore rule: vulnetix ignore add --rule vnx-444 --reason "...". See Suppressing findings.