CWE-86 covers a product that does not neutralize invalid characters or byte sequences in the middle of tag names, URI schemes and other identifiers.
It is a filter bypass problem for sites that try to block script by recognizing its name.
How it happens
Some web browsers remove invalid sequences, producing output with unintended control meaning. MITRE's example: the product tries to remove a "javascript:" URI scheme, but a "java%00script:" URI gets past the check, and some browsers still render it as active JavaScript. The filter saw one string, and the browser acted on another.
The observed example is CVE-2004-0595, an XSS filter that does not filter null characters before looking for dangerous tags, which are then ignored. See CVE-2004-0595.
What an attacker gains
MITRE lists confidentiality, integrity and availability: reading application data and running unauthorized code or commands.
How to find it
MITRE lists automated static analysis (SAST) for finding some instances by modeling data flow. Add tests with null bytes and other invalid sequences inserted into every identifier your filters look for.
How to fix it
MITRE's mitigation is to use and specify an output encoding the downstream component can handle, such as UTF-8. When no encoding is specified, a downstream component may guess, and inconsistent encodings let attackers slip characters past protections that assume the original encoding.
- Reject input that contains null bytes or other invalid characters.
- Set the character encoding on responses and keep it consistent.
- Escape output for its context, and allow only known good schemes.
Quick check
What happened in the java%00script example?
The filter did not see the scheme because of the null byte, but some browsers dropped the byte and ran the script.