CWE-166 is about input from an upstream component where an expected special element is missing, and the product does not handle that case. The code assumes a separator, terminator or delimiter will be there, and acts on a position that does not exist.
Network servers and message parsers are the main targets, because attackers can send malformed messages at will. MITRE records the impact as availability: a crash, exit or restart.
How it happens
The parser looks for a separator and then uses the result.
# Vulnerable: no check that the separator exists
def parse(line: str):
key, value = line.split(":", 1) # raises when ":" is missing
return key, value
In Python that raises an exception that may take down a worker. In lower level code the same assumption can read or write at a wrong offset.
The observed examples show the effect. CVE-2002-1362 is a crash from a message type without a separator character. CVE-2002-0729 is a missing special character, a separator, that causes a crash. CVE-2002-1532 is an HTTP GET without the carriage return and line feed sequences that makes the product wait indefinitely and blocks other users. The first two crash. The third hangs, which is the other face of the same bug: a parser waiting for a terminator that never comes.
What an attacker gains
The recorded impact is denial of service by crash, exit or restart. The HTTP example is a denial of service by blocking, since the server waits forever.
How to find it
MITRE lists no detection methods. Test short and truncated input.
- Send every message type with a separator removed, with the terminator removed, and cut off midway.
- Hold a connection open after sending a partial request and see whether the server recovers.
- Fuzz the protocol layer with truncated frames.
How to fix it
- Anticipate that special elements will be removed from the input.
- Check that the separator exists before using the result of a search, and fail with a clear error if not.
def parse(line: str):
if ":" not in line:
raise ValueError("malformed line: missing separator")
key, value = line.split(":", 1)
return key, value
- Put timeouts on reads that wait for a terminator, and cap the buffer size.
- Use an allowlist for acceptable input and reject what does not match its specification, taking length, syntax and consistency across related fields into account.
- Catch parse errors at the connection or message boundary so one bad message does not stop other users.
Quick check
Can a missing terminator cause denial of service without a crash?
Yes. In CVE-2002-1532 the server waited indefinitely for a missing sequence, which kept other users out.