Bug 59115

Summary: Part#getSubmittedFileName doesn't work corretly with double quotes in filenames.
Product: Tomcat 8 Reporter: Udo Schnurpfeil <lofwyr>
Component: Specification APIsAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: minor CC: csutherl, s05marti
Priority: P2    
Version: 8.0.32   
Target Milestone: ----   
Hardware: All   
OS: All   

Description Udo Schnurpfeil 2016-03-04 10:43:23 UTC
If using the File-Upload with Servlet 3.1 and selecting a file with name e.g. foo"bar".jpg the method call part.getHeader("Content-Disposition") results to e.g. form-data; name="file"; filename="foo-\"bar\".jpg".

The call of part.getSubmittedFileName() results to foo-\"bar\".jpg but should foo-"bar".jpg because the quotes are not part of the name.

The parsing problem may also affect other functions...
Comment 1 Mark Thomas 2016-03-04 17:29:34 UTC
Thanks for the report. The submitted file name is either a token or quoted-string and we weren't handling the quoted-string case.

This has been fixed for 9.0.x (9.0.0.M4 onwards), 8.0.x (8.0.33 onwards) and 7.0.x (7.0.69 onwards).
Comment 2 Udo Schnurpfeil 2016-03-04 19:26:46 UTC
Thanks for the quick response. I've just testet it with 8.0/trunk but it there was an Exception:
The replaceAll need a regexp, and so the quoted backslash needs to be quoted again:
replaceAll("\\\\", "") instead of replaceAll("\\", "")
Comment 3 Udo Schnurpfeil 2016-03-04 21:34:30 UTC
I've made some tests with different browsers and I found these encodings in the filename part:

(filename) -> (content-disposition)
: -> :
/ -> :
\ -> \
\\ -> \
" -> \" (Firefox) and %22 (Chrome+Safari)
%22 -> %22

This leads to 3 problems:
1. The resulting string : doesn't differ between : and / so there is not possibility to know what was the source.
2. The resulting string \ doesn't differ between \\ and \ so there is also not possibility to find the source.
3. In Chrome+Safari we cannot differ between " and %22

I know these character are unusual, but not invalid on some OS.

For the moment I have best results with this code:

fileName = fileName.trim().replaceAll("\\\\\\\"", "\""); // replaces \" with "

I don't know which RFC is relevant here? But it looks for me, that we have different file names 
resulting in same header information.
Comment 4 Mark Thomas 2016-03-05 16:07:00 UTC
I've fixed the initial exception.

The relevant spec here is RFC6266. I'm leaving this issue open until I have a chance to look through that spec.
Comment 5 Mark Thomas 2016-03-05 18:30:17 UTC
This has been fixed so Tomcat follows RFC 6266.

If some UAs do strange things outside of RFC 6266 then bugs need to be raised with those browsers in the first instance.
Comment 6 Marco 2016-07-18 19:21:20 UTC
This Change destroy the file upload in Internet-Explorer 11.

The "Content-Disposition" Header contains the filename with path 
form-data; name="Datei"; filename="D:\temp\test.xml".
The call of part.getSubmittedFileName() return "D:temptest.xml". Befor this change it returns "D:\temp\test.xml".
Comment 7 Mark Thomas 2016-07-19 10:55:03 UTC
IE 11 is not specification compliant. As per comment #5, you'll need to raise a bug with Microsoft in the first instance. In the meantime, you can manually parse the header yourself with custom rules for IE11 if you need that information.

If Microsoft refuse to fix the bug then you should open a new enhancement request for Tomcat to apply special handling in this case. There is no guarantee that such an enhancement request will be implemented. The Tomcat team generally does not implement work-arounds for bugs in third-party code.
Comment 8 Konstantin Kolinko 2016-07-19 13:00:45 UTC
Sending full file path is a rather odd and insecure behaviour. Is this IE 11 not up-to-date, or does this behaviour depend on its security settings (e.g. server being in trusted network)?

Some links

https://tools.ietf.org/html/rfc6266
https://tools.ietf.org/html/rfc1867
https://www.w3.org/TR/2014/REC-html5-20141028/forms.html#file-upload-state-(type=file)
http://commons.apache.org/proper/commons-fileupload/
Comment 9 Marco 2016-07-19 19:13:33 UTC
This option is in all Internet Explorer Version (8,9,10,11) for local and trusted networks present. The entry name is " Include local directory path when uploading files to a server". This entry is default enabled for trusted networks.
I don't need this information. But when the "\" character is removed i has no chance to extract the correct filename.
Comment 10 Mark Thomas 2016-07-21 19:54:58 UTC
*** Bug 59891 has been marked as a duplicate of this bug. ***
Comment 11 Konstantin Kolinko 2016-07-25 14:28:05 UTC
This needs further investigation.

Using RFC 6266 is an error: it defines a response header, not a request one.

Section "1. Introduction" of RFC 6266 has the following note:

      Note: This document does not apply to Content-Disposition header
      fields appearing in payload bodies transmitted over HTTP, such as
      when using the media type "multipart/form-data" ([RFC2388]).

Links:
https://tools.ietf.org/html/rfc6266
https://tools.ietf.org/html/rfc2388 (Obsoleted by: 7578)
https://tools.ietf.org/html/rfc7578
Comment 12 Mark Thomas 2016-08-02 18:10:38 UTC
So, starting with RFC7578:
Section 4.2 points to RFC2183 for the definition of the content disposition header.

RFC2183 defines:
filename-parm := "filename" "=" value
and points to RFC2045 for value

RFC2045
value := token / quoted-string
and points to RFC822

RFC822:
quoted-string = <"> *(qtext/quoted-pair) <">

qtext         =  <any CHAR excepting <">,
                  "\" & CR, and including
                  linear-white-space>

And this is what Tomcat currently implements.

There are lots up updates to these RFCs around i18n values. Browsers don't seem to be using them. We can update Tomcat if / when browsers start supporting them.

On the grounds Tomcat is adhering to the relevant RFCs and IE is not, I am re-resolving this issue as fixed.
Comment 13 Masahiro YAMADA 2016-10-20 10:26:37 UTC
I sent this problem to Microsoft.
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9440110/
Comment 14 Mark Thomas 2016-11-14 20:48:17 UTC
*** Bug 60371 has been marked as a duplicate of this bug. ***
Comment 15 Michael Osipov 2016-11-15 15:19:27 UTC
Not surpringly, Microsoft closed as wontfix.