VNX-792: Incomplete Filtering of One or More Instances of Special Elements
HTML escaping or script stripping that replaces only the first occurrence: JavaScript replace() with a string or non-global regex, Python replace(..., 1).
| Field | Value |
|---|---|
| Rule ID | VNX-792 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-792 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | incomplete-filtering-one-instance cwe-792 |
| Source | internal/sast/rules/vnx-792.rego |
Overview
VNX-792 maps to CWE-792: Incomplete Filtering of One or More Instances of Special Elements. It reports markup sanitising that handles only the first occurrence:
- JavaScript/TypeScript
String.replace()with a string literal, or a regex literal without thegflag, whose pattern is<,>,&, a quote, a<script/<iframetag,javascript:or an event-handler attribute, replaced with nothing or with an HTML entity - Python
str.replace(..., 1)andre.sub(..., count=1)with the same tokens
Global replacements (/g, replaceAll, Python’s default replace-all), template substitutions whose replacement is markup, and path or command tokens (reported by VNX-793) are not reported.
Why This Matters
In JavaScript, 'a<b<c'.replace('<', '<') returns a<b<c. Only the first bracket is escaped, so a payload that starts with a harmless < puts the next one into the page unescaped.
What Gets Flagged
return text.replace('<', '<') // FLAGGED
.replace(">", ">"); // FLAGGED
body = body.replace("<script>", ""); // FLAGGED
return s.replace(/</, '<'); // FLAGGED: no g flag
return s.replace("<", "<", 1) # FLAGGED
Remediation
- Use a context-aware encoder or the template engine’s auto-escaping.
- If you must replace by hand, use
replaceAllor a/gregex, and escape&first.
References
- CWE-792: Incomplete Filtering of One or More Instances of Special Elements
- MDN: String.prototype.replace()
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-792
// nosec vnx-792
Or record an ignore rule: vulnetix ignore add --rule vnx-792 --reason "...". See Suppressing findings.