VNX-622: Client-supplied JSONP callback name written into the response unvalidated
Reports a JSONP endpoint that writes a client-supplied callback name into a script response without validating it.
| Field | Value |
|---|---|
| Rule ID | VNX-622 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | JavaScript / TypeScript |
| CWE | CWE-622 |
| 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 | callback-validation jsonp cwe-622 |
| Source | internal/sast/rules/vnx-622.rego |
Overview
VNX-622 maps to CWE-622: Improper Validation of Function Hook Arguments. The general weakness has no static signature in application JavaScript, so this rule reports its most concrete server-side form: the client names the function the response will call (a JSONP callback), and the server writes that name into executable script unchecked. The caller then chooses what code runs in any page that loads the endpoint.
What Gets Flagged
res.send(req.query.callback + '(' + data + ');');
const cb = req.query.cb as string
res.send(`${cb}(${payload})`)
const callback = ctx.query.callback;
ctx.body = `${callback}(${JSON.stringify(stats)})`;
Not flagged: res.jsonp() (Express restricts the callback charset), a name sanitised with .replace() or checked with a regular expression before use, constant callback names, comments and string literals.
Remediation
Use res.jsonp(), or allow only identifier characters:
if (!/^[A-Za-z_$][\w$.]*$/.test(cb)) return res.status(400).end();
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-622
// nosec vnx-622
Or record an ignore rule: vulnetix ignore add --rule vnx-622 --reason "...". See Suppressing findings.