Repository navigation
Conversation
Parameter values were only validated as ASCII, so a value containing CR or LF was accepted and emitted raw by toString(), splitting any header the string is used in. Reject ISO control characters other than horizontal tab in normalizeParameterValue, which create, withParameter, withParameters and parse all funnel through.
There was a problem hiding this comment.
Code Review
This pull request introduces validation to prevent control characters (except horizontal tab) in MediaType parameter values, addressing potential header splitting issues. A security concern was raised regarding a potential log injection vulnerability (CWE-117) because the raw parameter value containing control characters is included in the exception message. It is recommended to omit the raw value from the error message to prevent log injection.
| checkArgument( | ||
| PARAMETER_VALUE_MATCHER.matchesAllOf(value), | ||
| "parameter values must not contain control characters: %s", | ||
| value); |
There was a problem hiding this comment.
Including the raw value in the exception message when it is known to contain control characters (such as \r or \n) can lead to log injection vulnerabilities (CWE-117) if the exception message is logged by the consuming application. Since this check only fails when value contains control characters, it is safer to omit the raw value from the error message.
checkArgument(
PARAMETER_VALUE_MATCHER.matchesAllOf(value),
"parameter values must not contain control characters");|
This is close enough to the earlier #8743 that I'm closing it in favor of that one. |
MediaType.create("text", "plain").withParameter("name", "evil\r\nX-Injected: 1").toString()
-> text/plain; name="evil<CR>X-Injected: 1"
Parameter values are only validated as ASCII, which includes the control characters. A quoted-string has no way to represent CR or LF (
escapeAndQuotebackslash-prefixes CR, but that does not make the raw byte legal), so both come out oftoString()as raw bytes, and anything that usesmediaType.toString()as a Content-Type value, like a multipart or MIME writer, ends up with a split header.parse()has the same gap on the way in:QUOTED_TEXT_MATCHERexcludes CR but not a bare LF, and the quoted-pair branch accepts any ASCII character, so a crafted value survives a parse/toString round trip.Reject control characters other than horizontal tab in
normalizeParameterValue, the single point thatcreate,withParameter,withParametersandparseall funnel through. Tab stays allowed because a quoted-string may contain it. Same reasoning as the ASCII restriction from #3626:toString()output is used in header values. The new tests fail without the change: