CORS complain even when headers are sent
Hi, I don't know if it's a firefox bug, or maybe a change made recently (in the CORS code) cuz firefox keeps complaining about the request being blocked (and I don't remember this happening, I remember the content of the file being displayed in the site, a json translation file, some months ago):
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://static.domain.com/js/DataTables-Spanish.json. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
I have the subdomain properly configured, in fact, the other requests like css/js files are being read and working without problems, but this particular request (made from inside a javascript file) is being blocked with a CORS error, even when I can see the header in the firefox network monitor:
Accept-Ranges: bytes Content-Length: 932 Content-Type: application/json Date: Thu, 05 Jan 2017 22:52:32 GMT Etag: "3a4-52ef9645b6940" Last-Modified: Sat, 26 Mar 2016 20:19:09 GMT Server: Apache/2.4.25 (Unix) OpenSSL/1.0.2j X-Firefox-Spdy: h2 access-control-allow-methods: GET strict-transport-security: max-age=63072000; includeSubdomains;
More information: http://stackoverflow.com/q/41495783/4067132
Izbrana rešitev
ChazyTheBest said
For some mysterious reason, all of my js and css files are not getting blocked by cors, that is, the ones requested from the html file. The jquery ajax request method, does trigger cors and the json file is getting blocked. ...
... Is cors supposed to block that GET request?
No, Firefox only enforces the same-origin rules in certain contexts. This should be mostly standardized among browsers. More info:
- https://developer.mozilla.org/docs/Web/Security/Same-origin_policy#Cross-origin_network_access
- https://en.wikipedia.org/wiki/Same-origin_policy
- (previously linked) https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Cross-site_XMLHttpRequest
Vsi odgovori (13)
Is Firefox/jQuery/DataTables sending the Origin header with the request? That might be the trigger for the server to send back the Access-Control-Allow-Origin header.
I really don't know. Doesn't firefox automatically do that? At least for the other requests, such as <link href=""> and <script src="">.
I'll take a look at the DataTables code and look for the part that does the request and see if it's a jquery get request method or what... but I think that should be a firefox thing, because i don't do any cors request to get the css/js files...
Spremenil ChazyTheBest
I just noticed that the origin header is sent in the json file request, all other files (the ones from the html) have a cookie header instead.
So yeah, firefox is sending the origin header with the request. And the server is returning the correct header (as I already said):
`access-control-allow-methods: GET`
What is going on then? Any way to get a dev to review this?
Spremenil ChazyTheBest
And the server is returning the correct header (as I already said):
`access-control-allow-methods: GET`
No, you misread it, that's a different header. The missing one Firefox requires is:
Access-Control-Allow-Origin
Any way to get a dev to review this?
Unlikely here, this is the user support forum and dev presence is rare.
Ok, is that a request or response header? I don't see it anywhere, not even on the other css/js files, so... how come all those files are not being blocked too?
I mean, I see the response headers for a js file and the only cors header I see is this one:
access-control-allow-methods: GET
And that js file is NOT being blocked (just like the rest of js/css files). I don't see any other cors header anywhere.... So why is only one file being blocked and not the rest? Argh!
The only place where I have the missing header is in the vhost block config for the static subdomain:
<IfModule mod_headers.c>
SetEnvIfNoCase Origin: "https?://(www\.)?(domain\.com|sub1\.domain\.com)(:\d+)?$" ACAO=$0 Header set Access-Control-Allow-Origin: "%{ACAO}e" env=ACAO Header set Access-Control-Allow-Methods: "GET"
</IfModule>
Spremenil ChazyTheBest
As far as I know, Firefox only needs to receive the Access-Control-Allow-Origin header for a cross-domain XMLHttpRequest call. (And then it needs to allow the requesting site.)
Are other browsers handling this in a different way (without using command line startup switches to disable the same origin rule)?
I tried chromium (in linux) and the same. My server only returns:
access-control-allow-methods:GET
I just saw a CDN header and efectively it's returning:
Access-Control-Allow-Headers: origin, x-requested-with, content-type Access-Control-Allow-Origin: *
Alongside the one above. So maybe my server is not well configured?
ChazyTheBest said
The only place where I have that is in the vhost block config for the static subdomain:<IfModule mod_headers.c> SetEnvIfNoCase Origin: "https?://(www\.)?(domain\.com|sub1\.domain\.com)(:\d+)?$" ACAO=$0 Header set Access-Control-Allow-Origin: "%{ACAO}e" env=ACAO Header set Access-Control-Allow-Methods: "GET" </IfModule>
Environment variables, I don't know about those. Your code looks like this highly voted model as well as many others on the web: http://stackoverflow.com/a/1850482
But those do not have a colon after SetEnvIfNoCase Origin -- could Apache be requiring that as part of the actual header name?
Yeah, i took the code from a highly voted question in stackoverflow and modified it to my needs.
That first line is a regex, to match my domain (with or without www) and (currently) a subdomain (and whether http or https). That way I can specify only the allowed domains/subdomains instead of just using the wildcard (seems insecure).
I'm gonna try removing the colon, i put it because I remember I was getting errors and it looks like it needed it and it was working ok until.
I found that it works if I use the wildcard instead of the regex:
<IfModule mod_headers.c> #SetEnvIfNoCase Origin: "https?://(www\.)?(domain\.com|sub1\.domain\.com)(:\d+)?$" ACAO=$0 #Header set Access-Control-Allow-Origin: "%{ACAO}e" env=ACAO Header set Access-Control-Allow-Origin: * Header set Access-Control-Allow-Methods: "GET" </IfModule>
I guess i'll have to ask in stackoverflow or better in the apache forums.
Spremenil ChazyTheBest
Ok, I found the problem, but still don't know whose fault is.
The thing is that apache is not sending the Access-Control-Allow-Origin header in any request. Only the Access-Control-Allow-Methods header is getting sent.
For some mysterious reason, all of my js and css files are not getting blocked by cors, that is, the ones requested from the html file. The jquery ajax request method, does trigger cors and the json file is getting blocked.
The difference between a request from html and one from jquery ajax method is a header:
html requests send this one -> Cookie: session_id_name=isafcbcb7v7en7hm8gqkkb6as4
jquery ajax requests send this one instead -> Origin: https://sub1.domain.com
Now, if i change the order of the headers and put the important one in the last line, then It will send it but only for the ajax request, still not for the other files:
SetEnvIf Origin "https://(www.domain.com|sub1.domain.com|auth.domain.com)$" ACAO=$0 Header set Access-Control-Allow-Methods "GET" Header always append Access-Control-Allow-Origin "%{ACAO}e" env=ACAO
I think I still don't know how cors works exactly (more specifically what type of requests/files does block), i'm still confused... So could you please tell me if cors is supposed to block html requests? Example:
<link rel="stylesheet" type="text/css" media="all" href="//static.domain.com/css/dropzone.css" />
Is cors supposed to block that GET request?
Spremenil ChazyTheBest
Izbrana rešitev
ChazyTheBest said
For some mysterious reason, all of my js and css files are not getting blocked by cors, that is, the ones requested from the html file. The jquery ajax request method, does trigger cors and the json file is getting blocked. ...
... Is cors supposed to block that GET request?
No, Firefox only enforces the same-origin rules in certain contexts. This should be mostly standardized among browsers. More info:
Spremenil jscher2000 - Support Volunteer
Thank you so much! Now I fully understand what was happening.
I was using SetEnvIfNoCase, that was doing just the opposite of what I wanted. And the order doesn't matter:
SetEnvIf Origin "https://(www.domain.com|sub1.domain.com|auth.domain.com)$" ACAO=$0 Header always append Access-Control-Allow-Origin "%{ACAO}e" env=ACAO Header set Access-Control-Allow-Methods "GET"