VNX-182: Collapse of Data into Unsafe Value
Reports a single-pass removal of a traversal sequence (../, ..\, ..), a <script> tag or (in a filter chain) a http:// scheme by replacing it with the empty string, which lets the surrounding characters collapse back into the token.
| Field | Value |
|---|---|
| Rule ID | VNX-182 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Python, JavaScript / TypeScript, Java, C#, Go, PHP |
| CWE | CWE-182 |
| CAPEC | CAPEC-66 |
| 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 | collapse sanitization path-traversal xss cwe-182 |
| Source | internal/sast/rules/vnx-182.rego |
Overview
VNX-182 maps to CWE-182: Collapse of Data into Unsafe Value. It reports a call that removes a dangerous token from a string by replacing it with the empty string, once:
- Python
str.replaceandre.sub - JavaScript/TypeScript
replace/replaceAllwith a string or regex literal - Java
replace/replaceAll/replaceFirst, C#Replaceand staticRegex.Replace - Go
strings.Replace/strings.ReplaceAll,strings.NewReplacerandregexp.MustCompile(...).ReplaceAllString - PHP
str_replace/str_ireplace, including the array form, andpreg_replace
The tokens are traversal sequences (../, ..\, .., or a regex such as \.\.[\/\\]), <script>/</script> (or a regex for the whole element, <script[^>]*>.*?</script>) and javascript:. Stripping http:///https:// is reported only when it sits within three lines of one of those removals, because on its own it is usually display normalisation.
Not reported: a removal repeated in a while/do-while loop until the token is gone, a removal whose result is checked for the token again and rejected within four lines, a prefix trim (TrimPrefix), a replacement with a non-empty value (escaping, such as <), other tokens, the call written inside a string literal, and comments.
This rule is the one finding for these removals: VNX-76 does not report the same line again, and keeps the sequences this rule does not judge (other tags, vbscript:, shell operators, SQL and script keywords).
Why This Matters
Removing a token once does not mean the result is free of it. "....//".replace("../", "") returns ../, "<scr<script>ipt>" becomes <script>, and "hthttp://tp://" becomes http://. A filter written this way gives a false sense of safety in front of a file read, an include or an HTML response.
What Gets Flagged
// FLAGGED
$file = str_replace(array("../", "..\\"), '', $file);
$name = str_ireplace('<script>', '', $name);
# FLAGGED
name = name.replace("../", "")
cleaned = re.sub(r"\.\./", "", raw)
// FLAGGED
name = strings.ReplaceAll(name, "../", "")
// FLAGGED
var clean = Regex.Replace(body, "<script>", "", RegexOptions.IgnoreCase);
# NOT FLAGGED: repeated until stable
while "../" in name:
name = name.replace("../", "")
Remediation
- Reject input that contains the token instead of rewriting it.
- For paths, canonicalise (
os.path.realpath,filepath.Clean,Path.normalize) and check that the result is still under the base directory. - For HTML, encode on output with the template engine or
htmlspecialchars; do not strip tags.
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-182
// nosec vnx-182
Or record an ignore rule: vulnetix ignore add --rule vnx-182 --reason "...". See Suppressing findings.