Affects: 5.3.21
When a multipart request contains a part with a quote or backslash in the name or filename, it should be escaped. ContentDisposition properly escapes them when building the header, but it does not unescape them when parsing it. See the following code:
ContentDisposition cd = ContentDisposition.builder("form-data").name("file").filename("a\\nice \"file\" with \\\" quotes.txt").build();
System.out.println("Generated header: " + cd);
System.out.println("Original: " + cd.getFilename());
ContentDisposition parsed = ContentDisposition.parse(cd.toString());
System.out.println("Parsed: " + parsed.getFilename());
output:
Generated header: form-data; name="file"; filename="a\nice \"file\" with \" quotes.txt"
Original: a\nice "file" with \" quotes.txt
Parsed: a\nice \"file\" with \" quotes.txt
(also note that the last quote seems to be considered as already escaped so it does not get escaped – seems intentional from the original implementation in 956ffe6)
The issue seems to come from ContentDisposition.java#L354-L356, which simply removes the outer quotes without unescaping:
String value = (part.startsWith("\"", eqIndex + 1) && part.endsWith("\"") ?
part.substring(eqIndex + 2, part.length() - 1) :
part.substring(eqIndex + 1));
We noticed this issue because we were seeing \" from MultipartFile.getOriginalFilename(), whereas Servlet’s Part.getSubmittedFileName() returns the correct value.
Affects: 5.3.21
When a multipart request contains a part with a quote or backslash in the
nameorfilename, it should be escaped.ContentDispositionproperly escapes them when building the header, but it does not unescape them when parsing it. See the following code:output:
(also note that the last quote seems to be considered as already escaped so it does not get escaped – seems intentional from the original implementation in 956ffe6)
The issue seems to come from
ContentDisposition.java#L354-L356, which simply removes the outer quotes without unescaping:We noticed this issue because we were seeing
\"fromMultipartFile.getOriginalFilename(), whereas Servlet’sPart.getSubmittedFileName()returns the correct value.