Skip to content

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.

Updated 02 Nov 2026Checked against cli@de9b52a
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

  1. Validate header values against an allow-list (for example a fixed set of languages).
  2. Encode what must be reflected: content-disposition or RFC 5987 filename*= encoding, encodeURIComponent, urllib.parse.quote.
  3. Strip CR and LF from any value that reaches a header.

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-644
// nosec vnx-644

Or record an ignore rule: vulnetix ignore add --rule vnx-644 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-644.rego, cli/internal/sast/docs/vnx-644.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.