document.styleSheets.cssRules is null even with Access-Control-Allow-Origin: *
Reported by
br...@amazon.com,
Jan 23 2018
|
||||||
Issue description
UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/63.0.3239.84 Chrome/63.0.3239.84 Safari/537.36
Steps to reproduce the problem:
1. Create some directory and cd to it, e.g. /tmp/css_cors_bug
2. Make a file css_cors_bug.html in the directory:
```
<html>
<body>
<!-- Inline style. Styles accessible from Javascript. -->
<style>
body {
background-color: linen;
}
</style>
<!-- Externally hosted stylesheet. curl it and you'll see it simply
defines a @font-face with font properties. Styles *inaccessible* from
Javascript. -->
<link href="http://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet">
<!-- Adaptation of the external stylesheet, but hosted on the same --
-- domain as the main page. Styles accessible from Javascript. -->
<link href="local_roboto.css" rel="stylesheet">
<p style="font-family:Roboto;">Here is some Roboto text</p>
<p style="font-family:Roboto-Local">Here is some Robot-Local text</p>
<script>
// prints:
// rule: {"0":{}}
// rule: null
// rule: {"0":{}}
for(var ss of document.styleSheets) {
console.log("rule: " + JSON.stringify(ss.cssRules));
}
</script>
</body>
</html>
```
3. Make a file local_roboto.css in the same directory:
```
@font-face {
font-family: 'Roboto-Local';
font-style: normal;
font-weight: 800;
src: local('Roboto-Local'), local('Roboto-Regular-Local'), url(https://fonts.gstatic.com/s/roboto/v18/zN7GBFwfMP4uA6AR0HCoLQ.ttf) format('truetype');
font-display: block;
}
```
4. Serve the directory on some port using tool of choice, example below:
```
python -m SimpleHTTPServer 4444
```
5. Visit localhost:4444/css_cors_bug.html
6. Observe the dev tools console output:
```
rule: {"0":{}}
rule: null
rule: {"0":{}}
```
What is the expected behavior?
The second cssRule printed in step 6 above should also be {"0":{}} rather than null.
What went wrong?
The second cssRule printed in step 6 above is null.
Did this work before? N/A
Does this work in other browsers? N/A
Chrome version: 63.0.3239.84 Channel: n/a
OS Version: 16.04
Flash Version:
I believe there may be a bug in the CORS logic. My understanding is that Chromium will nullify the cssRules property on stylesheets loaded from other domains if the stylesheet response from those domains does not include the correct CORS headers. This would explain the happy case where both the inline stylesheet and the stylesheet loaded from the same domain (localhost:4444) provide access to the cssRules property. However, the cross-domain stylesheet shown in the above examples does in fact return Access-Control-Allow-Origin: *, and so I would have expected that the cssRules property would not have been nullified in this case:
```
$ curl -i http://fonts.googleapis.com/css?family=Roboto
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Timing-Allow-Origin: *
Expires: Tue, 23 Jan 2018 00:29:37 GMT
Date: Tue, 23 Jan 2018 00:29:37 GMT
Cache-Control: private, max-age=86400
Server: ESF
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Accept-Ranges: none
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/css; charset=utf-8
Connection: keep-alive
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v18/zN7GBFwfMP4uA6AR0HCoLQ.ttf) format('truetype');
}
```
Is this behavior intentional, or should cssRules be readable from Javascript for stylesheets retrieved cross-domain, assuming the stylesheet response includes the correct CORS headers?
,
Jan 23 2018
,
Jan 23 2018
Takashi, please have a look. This reproduces as described. I don't understand CORS well enough to know whether this is intentional behaviour or not. Since the .css in question has a "Access-Control-Allow-Origin: *" header set, I'd guess it isn't.
,
Mar 9 2018
I'm doing triage on assigned bugs.
,
Mar 9 2018
Current Stable Chrome and Firefox raises a SecurityError on the second rule access instead of returning null. I guess this is intentional, but let me check the spec. I'm actually not familiar with stylesheet specific CORS behavior at this point. CC: mkwst if he already knew a right answer.
,
Mar 9 2018
Well, you just need to set crossorigin attribute to the link tag. Without this attribute, CORS is not checked at all. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by ajha@chromium.org
, Jan 23 2018