CWE-145 applies when the product receives input from an upstream component but does not neutralize, or incorrectly neutralizes, special elements that could be read as section delimiters by a downstream component. It is a variant of CWE-140 and is language-neutral. MITRE's record lists no observed CVEs for it.
How it happens
A section delimiter splits a document or message into parts. MITRE gives an example: the boundary string in a multipart MIME message. It adds that in many cases, doubled line delimiters can serve as a section delimiter, as with the blank line between HTTP or mail headers and the body.
If the program places user data into a part and the data contains the boundary string, or a blank line, the parser may close the section early. What follows is then read as a new section, with its own headers and meaning.
# Vulnerable: boundary is fixed and user text is not checked
BOUNDARY = "xyz123"
body = ("--" + BOUNDARY + "\r\n" + "Content-Type: text/plain\r\n\r\n"
+ user_text + "\r\n--" + BOUNDARY + "--\r\n")
# user_text containing the boundary line can start a forged part
MITRE notes that an injected, absent or malformed delimiter may cause the process to take unexpected actions.
What an attacker gains
The listed consequence is an integrity impact with an unexpected state. The attacker can introduce parts that the sender never wrote, or split a header block from its body so that later content is interpreted differently.
How to find it
- Find every place you build multipart bodies, header blocks or sectioned documents by hand.
- Submit values containing the boundary pattern and blank lines.
- Check what the receiver does when it sees an early boundary.
How to fix it
- Use a library that builds multipart messages and chooses a random boundary that does not occur in the content.
- Reject or encode blank lines and boundary-like text in single-section fields.
- Encode binary or free text content, for example with base64, so it cannot contain a boundary.
- Validate headers for line breaks before writing them.
Quick check
Why choose a random boundary?
A boundary that cannot be predicted and is checked against the content cannot be forged by an attacker who controls part of the data.