RESOLVED FIXED 155761
Origin header is not included in CORS requests for preloaded cross-origin resources
https://bugs.webkit.org/show_bug.cgi?id=155761
Summary Origin header is not included in CORS requests for preloaded cross-origin res...
Josh Dover
Reported 2016-03-22 11:46:38 PDT
According to the CORS specification [1], all CORS requests must include the 'Origin' header. Many server and CDN implementations will not respond with any of the appropriate CORS headers if the Origin is not specified. When a resource is referenced by a `<link>` tag, WebKit does not include the Origin in the request. While WebKit does still accept the resource as valid, it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet (it will be `null` for tainted stylesheets). I confirmed this is the case via `tcpdump` with Safari 9.0.3 (11601.4.4) and got the same results in WebKit nightly r198522. Example tag used: ``` <link href="//mycdn.com/style.css" rel="stylesheet" type="text/css" media="all" crossorigin="use-credentials"> ``` Recorded Safari request, note the missing Origin header: ``` 13:39:48.413187 IP 10.0.1.136.50969 > 69.172.201.208.http: Flags [P.], seq 2207105597:2207105953, ack 4251157642, win 65535, length 356: HTTP: GET /style.css HTTP/1.1 $...7.8...y...E.....@.@... ...E......P...=.c..P.......GET /style.css HTTP/1.1 Host: mycdn.com Accept-Encoding: gzip, deflate Connection: keep-alive Accept: text/css,*/*;q=0.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4 Accept-Language: en-us Referer: http://my.dev:5000/designer/181021729 Cache-Control: max-age=0 ``` Recorded Chrome request, note the Origin header: ``` 13:38:33.594253 IP 10.0.1.136.50856 > 69.172.201.208.http: Flags [P.], seq 4043612470:4043612873, ack 2525948378, win 65535, length 403: HTTP: GET /style.css HTTP/1.1 $...7.8...y...E.....@.@... ...E......P...6....P.......GET /style.css HTTP/1.1 Host: mycdn.com Connection: keep-alive Cache-Control: max-age=0 Accept: text/css,*/*;q=0.1 Origin: http://my.dev:5000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 Referer: http://my.dev:5000/designer/181021729 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8 ``` I've confirmed that Firefox + Chrome (example above) both handle this correctly. Safari also behaves the same if the `crossorigin` attribute set to 'use-credentials' or 'anonymous'. This could be a security threat since some developers may naively opt to send `Access-Control-Allow-Origin: *` as a workaround for this Safari-specific issue. Additionally, this poses an issue for anyone using a CDN that has limited CORS configuration options. For instance, AWS S3 will not send CORS headers if there is no Origin header, regardless of configuration. [1] http://www.w3.org/TR/cors/#origin-request-header
Attachments
Patch (15.01 KB, patch)
2016-06-09 05:33 PDT, youenn fablet
no flags
Archive of layout-test-results from ews117 for mac-yosemite (1.42 MB, application/zip)
2016-06-09 06:31 PDT, Build Bot
no flags
Updating test (15.94 KB, patch)
2016-06-10 05:44 PDT, youenn fablet
no flags
Josh Dover
Comment 1 2016-03-22 11:48:40 PDT
This is also a bug that many others have experienced. A good list of related issues on github: https://github.com/photonstorm/phaser/issues/1355#issuecomment-64144909
Radar WebKit Bug Importer
Comment 2 2016-03-24 18:28:26 PDT
Josh Dover
Comment 3 2016-06-06 12:15:03 PDT
Anyone looking for a SAFE workaround should not be using `Access-Control-Allow-Origin: *`. What I used that worked: - Find the CSSStyleSheet in the `tainted` state (`styleSheet.cssRules` will be null). - Make an XHR for the stylesheet's `href` - Add a new <style> node to the document's head with the contents of the XHR. - Optionally, remove the original style tag This method will be safe since you are still relying on the browser's CORS protections when you make the XHR.
Alexey Proskuryakov
Comment 4 2016-06-06 14:01:14 PDT
> While WebKit does still accept the resource as valid, it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet Do you have a complete test case demonstrating that CSSRuleList cannot be accessed from a script in WebKit?
youenn fablet
Comment 5 2016-06-09 02:20:58 PDT
I also confirm the issue.
youenn fablet
Comment 6 2016-06-09 05:33:55 PDT
youenn fablet
Comment 7 2016-06-09 05:37:37 PDT
(In reply to comment #6) > Created attachment 280913 [details] > --no-review This patch makes preload scanner use CORS mode for all preloaded resources that have crossorigin attribute, not only CSS stylesheets. HTMLLinkElement is also updated to make use of the attribute.
Build Bot
Comment 8 2016-06-09 06:31:50 PDT
Comment on attachment 280913 [details] Patch Attachment 280913 [details] did not pass mac-debug-ews (mac): Output: http://webkit-queues.webkit.org/results/1472290 New failing tests: editing/selection/selection-in-iframe-removed-crash.html
Build Bot
Comment 9 2016-06-09 06:31:54 PDT
Created attachment 280917 [details] Archive of layout-test-results from ews117 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews117 Port: mac-yosemite Platform: Mac OS X 10.10.5
youenn fablet
Comment 10 2016-06-09 08:16:30 PDT
(In reply to comment #8) > Comment on attachment 280913 [details] > Patch > > Attachment 280913 [details] did not pass mac-debug-ews (mac): > Output: http://webkit-queues.webkit.org/results/1472290 > > New failing tests: > editing/selection/selection-in-iframe-removed-crash.html Failing test seems not relevant to the changes. I'll check further though.
Ryan Haddad
Comment 11 2016-06-09 09:11:30 PDT
(In reply to comment #10) > (In reply to comment #8) > > Comment on attachment 280913 [details] > > Patch > > > > Attachment 280913 [details] did not pass mac-debug-ews (mac): > > Output: http://webkit-queues.webkit.org/results/1472290 > > > > New failing tests: > > editing/selection/selection-in-iframe-removed-crash.html > > Failing test seems not relevant to the changes. > I'll check further though. The failure may be related to http://trac.webkit.org/changeset/201823
Alex Christensen
Comment 12 2016-06-09 09:39:59 PDT
> it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet (it will be `null` for tainted stylesheets) This doesn't seem to be tested in the test. Is this really the case? If we can just get the computed style of an element effected by the stylesheet, what is the point of not being able to access the CSSRuleList?
youenn fablet
Comment 13 2016-06-09 11:31:31 PDT
(In reply to comment #12) > > it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet (it will be `null` for tainted stylesheets) > This doesn't seem to be tested in the test. Is this really the case? If we > can just get the computed style of an element effected by the stylesheet, > what is the point of not being able to access the CSSRuleList? I can add such test but I guess there are already tests somewhere ensuring that tainted stylesheets are not accessible in details through JS, similarly to tainted images in canvas.
youenn fablet
Comment 14 2016-06-10 05:39:49 PDT
(In reply to comment #13) > (In reply to comment #12) > > > it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet (it will be `null` for tainted stylesheets) > > This doesn't seem to be tested in the test. Is this really the case? If we > > can just get the computed style of an element effected by the stylesheet, > > what is the point of not being able to access the CSSRuleList? > > I can add such test but I guess there are already tests somewhere ensuring > that tainted stylesheets are not accessible in details through JS, similarly > to tainted images in canvas. I was too optimistic. Access to cssRules is governed by CSSStyleSheet::canAccessRules. This routine is checking whether the stylesheet URL is same-origin as the owner document origin. It does not take into account CORS. This issue being different and specific to CSS, I think it would be best tackled as a follow-up bug. I'll upload a patch with an updated test.
youenn fablet
Comment 15 2016-06-10 05:44:42 PDT
Created attachment 281006 [details] Updating test
youenn fablet
Comment 16 2016-06-10 05:45:33 PDT
(In reply to comment #15) > Created attachment 281006 [details] > Updating test To show the cssRules specific issue, one can just uncomment line 25 of the new test.
youenn fablet
Comment 17 2016-06-10 09:31:37 PDT
(In reply to comment #16) > (In reply to comment #15) > > Created attachment 281006 [details] > > Updating test > > To show the cssRules specific issue, one can just uncomment line 25 of the > new test. Note also that the patch is not enforcing full cross origin checks yet. Loading should fail if cross origin is set but Allow-Control-Allow-Origin is not in the response headers. This is the target of another bug.
WebKit Commit Bot
Comment 18 2016-06-10 11:15:40 PDT
Comment on attachment 281006 [details] Updating test Clearing flags on attachment: 281006 Committed r201930: <http://trac.webkit.org/changeset/201930>
WebKit Commit Bot
Comment 19 2016-06-10 11:15:46 PDT
All reviewed patches have been landed. Closing bug.
youenn fablet
Comment 20 2016-06-14 01:00:15 PDT
(In reply to comment #14) > (In reply to comment #13) > > (In reply to comment #12) > > > > it is marked as 'tainted' which prevents JavaScript on the page from accessing the CSSRuleList object on the CSSStyleSheet (it will be `null` for tainted stylesheets) > > > This doesn't seem to be tested in the test. Is this really the case? If we > > > can just get the computed style of an element effected by the stylesheet, > > > what is the point of not being able to access the CSSRuleList? > > > > I can add such test but I guess there are already tests somewhere ensuring > > that tainted stylesheets are not accessible in details through JS, similarly > > to tainted images in canvas. > > I was too optimistic. > Access to cssRules is governed by CSSStyleSheet::canAccessRules. > This routine is checking whether the stylesheet URL is same-origin as the > owner document origin. > It does not take into account CORS. > > This issue being different and specific to CSS, I think it would be best > tackled as a follow-up bug. > I'll upload a patch with an updated test. I filed bug 158728 for that purpose.
Note You need to log in before you can comment on or make changes to this bug.