VNX-644: HTTP response header set from request data without neutralisation
Reports a response header (Flask/Django headers, Express/Fastify setHeader/set/header/append, Node writeHead, Koa ctx.set) whose value is a request value, directly or through a variable, with no encoder or sanitiser. Constant and encoded values are not reported.
| Field | Value |
|---|---|
| Rule ID | VNX-644 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-644 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | header-injection http-headers cwe-644 |
| Source | internal/sast/rules/vnx-644.rego |
Overview
VNX-644 maps to CWE-644: Improper Neutralization of HTTP Headers for Scripting Syntax. It reports a response header whose value is copied from the request (query string, form, path parameter, body, cookie or another request header), on the same line or through a variable assigned up to 10 lines above, with no encoding in between.
Why This Matters
Headers are read raw by browsers, proxies, caches, log viewers and plug-ins. A reflected value can carry script syntax that one of those components renders, or CR/LF characters that split the response (CWE-113) where the framework does not reject them.
What Gets Flagged
resp.headers["Content-Disposition"] = "attachment; filename=" + request.args["file"]
response["Content-Disposition"] = f'attachment; filename="{name}.csv"' # name = request.GET.get(...)
res.setHeader('Content-Disposition', 'attachment; filename=' + req.params.name);
res.set('X-Client-Tag', req.query.tag);
res.writeHead(200, { 'Content-Type': 'text/html', 'X-Name': q.name }); // q from url.parse(req.url, true)
ctx.set('X-Request-Name', ctx.query.name);
Not flagged: constant values, contentDisposition(req.params.name), encodeURIComponent(...), parseInt(...), quote(name), a value cleaned with .replace(/[\r\n]/g, ''), and writes to the request’s own headers.
Remediation
- Validate header values against an allow-list (for example a fixed set of languages).
- Encode what must be reflected:
content-dispositionor RFC 5987filename*=encoding,encodeURIComponent,urllib.parse.quote. - Strip CR and LF from any value that reaches a header.
References
- CWE-644: Improper Neutralization of HTTP Headers for Scripting Syntax
- CWE-113: HTTP Response Splitting
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-644
// nosec vnx-644
Or record an ignore rule: vulnetix ignore add --rule vnx-644 --reason "...". See Suppressing findings.