New issue
Advanced search Search tips

Issue 919735 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner:
Closed: Jan 16
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 1
Type: Bug-Security



Sign in to add a comment

Security: when get a HTTP/1.1 message containing an entity-body which not include a Content-Type header field defining the media type of that body, CHROME will attempt to guess the media type via inspection of its content.

Reported by iamnicke...@gmail.com, Jan 8

Issue description

VERSION:   
    Chrome Version: all
    Operating System: all

DETAILS:
    I found that when get a HTTP/1.1 message containing an entity-body which not include a Content-Type header field defining the media type of that body, CHROME will attempt to guess the media type via inspection of its content. yet, it's truly comply with HTTP/1.1 . 
    for example, when a HTTP/1.1 message containing an entity-body not include a Content-Type header field defining the media type of that body, if its centent is '<script>alert(0)</script>' , CHROME will treat it as a text/html type. 
   there is a test link: 'http://wdwzqq.com.cn/test/test'. Such a behavior to treat a HTTP/1.1 message containing an entity-body without a Content-Type header field, make it possible to attack the browser user, when attacker can upload a none-type file to the server(or can edit a none-type file in the server).

accoding to RFC 2616 section 7.2.1:
    Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. ` if and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource. If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream".

EXAMPLE:
there is a example to use above property to attack browser user. 
	1) a picture can been uploaded to 'www.test.com/ipload/img/'
	2) 'test' server limits the file type(jpg/png) that can been uploaded, and the server save these file with a original name.
	3) upload a file name '.jpg' is allowed.and it will been saved with its original name '.jgp'
	4) attacker upload a file name '.jpg' to 'www.test.com/ipload/img/'(the '.jpg' is a fake login web page or within a aggressive javavscript text )
	5) browser user is leaded to request the fake web page 'www.test.com/ipload/img/.jpg' (user input his ID and pwd) and 'login'
	6)attack finished.

Reporter credit:
    topseczhengweikang
 
test
25 bytes View Download

Comment 1 Deleted

Components: Internals>Network
Labels: OS-Android OS-Chrome OS-Linux OS-Mac OS-Windows Pri-1
Owner: mef@chromium.org
Status: Assigned (was: Unconfirmed)
mef: Can you help route this?
I see that 'http://wdwzqq.com.cn/test/test' indeed returns base64-encoded text without specifying Content-Type.
Chrome appears to detect base64 encoding, decode it and interpret as text/html:

<script>alert(0)</script>

I'm not quite sure that I understand security implications. 

According to the comment at the top of https://cs.chromium.org/chromium/src/net/base/mime_sniffer.cc it is working as intended:

// Detecting mime types is a tricky business because we need to balance
// compatibility concerns with security issues.  Here is a survey of how other
// browsers behave and then a description of how we intend to behave.
//
// HTML payload, no Content-Type header:
// * IE 7: Render as HTML
// * Firefox 2: Render as HTML
// * Safari 3: Render as HTML
// * Opera 9: Render as HTML
//
// Here the choice seems clear:
// => Chrome: Render as HTML

Am I missing something?

33240: URL_REQUEST
http://wdwzqq.com.cn/test/test
Start Time: 2019-01-08 16:52:12.586

t=50573 [st=  0] +REQUEST_ALIVE  [dt=812]
                  --> priority = "HIGHEST"
                  --> url = "http://wdwzqq.com.cn/test/test"
t=50573 [st=  0]    NETWORK_DELEGATE_BEFORE_URL_REQUEST  [dt=0]
t=50573 [st=  0]   +URL_REQUEST_START_JOB  [dt=812]
                    --> load_flags = 1026 (BYPASS_CACHE | MAIN_FRAME_DEPRECATED)
                    --> method = "GET"
                    --> privacy_mode = 0
                    --> url = "http://wdwzqq.com.cn/test/test"
t=50573 [st=  0]      NETWORK_DELEGATE_BEFORE_START_TRANSACTION  [dt=0]
t=50574 [st=  1]      HTTP_CACHE_GET_BACKEND  [dt=0]
t=50574 [st=  1]      HTTP_CACHE_DOOM_ENTRY  [dt=0]
t=50574 [st=  1]      HTTP_CACHE_CREATE_ENTRY  [dt=0]
t=50574 [st=  1]      HTTP_CACHE_ADD_TO_ENTRY  [dt=0]
t=50574 [st=  1]     +HTTP_STREAM_REQUEST  [dt=582]
t=50574 [st=  1]        HTTP_STREAM_JOB_CONTROLLER_BOUND
                        --> source_dependency = 33242 (HTTP_STREAM_JOB_CONTROLLER)
t=51156 [st=583]        HTTP_STREAM_REQUEST_BOUND_TO_JOB
                        --> source_dependency = 33243 (HTTP_STREAM_JOB)
t=51156 [st=583]     -HTTP_STREAM_REQUEST
t=51156 [st=583]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=0]
t=51156 [st=583]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS
                        --> GET /test/test HTTP/1.1
                            Host: wdwzqq.com.cn
                            Connection: keep-alive
                            Pragma: no-cache
                            Cache-Control: no-cache
                            Upgrade-Insecure-Requests: 1
                            User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3665.0 Safari/537.36
                            Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
                            Accept-Encoding: gzip, deflate
                            Accept-Language: en-US,en;q=0.9
t=51156 [st=583]     -HTTP_TRANSACTION_SEND_REQUEST
t=51157 [st=584]     +HTTP_TRANSACTION_READ_HEADERS  [dt=228]
t=51157 [st=584]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=228]
t=51385 [st=812]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                        --> HTTP/1.1 200 OK
                            Date: Tue, 08 Jan 2019 21:52:13 GMT
                            Server: Apache/2.4.34 (Ubuntu)
                            Last-Modified: Mon, 07 Jan 2019 07:16:27 GMT
                            ETag: "1a-57ed901d26e53"
                            Accept-Ranges: bytes
                            Content-Length: 26
                            Keep-Alive: timeout=5, max=100
                            Connection: Keep-Alive
t=51385 [st=812]     -HTTP_TRANSACTION_READ_HEADERS
t=51385 [st=812]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=51385 [st=812]      HTTP_CACHE_WRITE_DATA  [dt=0]
t=51385 [st=812]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=51385 [st=812]      NETWORK_DELEGATE_HEADERS_RECEIVED  [dt=0]
t=51385 [st=812]   -URL_REQUEST_START_JOB
t=51385 [st=812]    URL_REQUEST_DELEGATE_RESPONSE_STARTED  [dt=0]
t=51385 [st=812]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=51385 [st=812]    URL_REQUEST_JOB_FILTERED_BYTES_READ
                    --> byte_count = 26
                    --> bytes = "PHNjcmlwdD5hbGVydCgwKTwvc2NyaXB0Pgo="
t=51385 [st=812]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=51385 [st=812] -REQUEST_ALIVE

Comment 4 by jdeblasio@chromium.org, Jan 16 (6 days ago)

Labels: -Restrict-View-SecurityTeam
Status: WontFix (was: Assigned)
To me this looks like WAI. Indeed, the standard the reporter quotes says explicitly "if and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection and/or the name extension(s)".

As a result, I'm going to close as WontFix, since this seems like a failure of a server, rather than the failure of the user agent. If the reporter has a different, more egregious example, we're always happy to revisit.

Sign in to add a comment