spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

ContentDisposition does not unescape quotes and backslashes when parsing

Open DidierLoiseau opened this issue 3 years ago • 0 comments

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 956ffe68587c8d5f21135b5ce4650af0c2dea933)

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.

DidierLoiseau avatar Jul 18 '22 15:07 DidierLoiseau

Fixing this will be a breaking change, so setting for 6.0.

poutsma avatar Sep 06 '22 13:09 poutsma