New issue
Advanced search Search tips

Issue 734378 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 2
Type: Bug



Sign in to add a comment

CORS headers with max-age persist even a after changing Access-Control-Allow-Origin

Reported by u...@umur.io, Jun 18 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

Steps to reproduce the problem:
1. Make a cross-domain (XMLHttpRequest) request and send a response with headers as follows:
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
2. Now change server settings to send the following CORS headers (replace domain name with proper origin):
Access-Control-Allow-Origin: {{ YOUR_ORIGIN }}
3. Profit

What is the expected behavior?
The browser should respect the new CORS headers, either by merging them or overwriting them.

What went wrong?
Browser adds the header it cache to the response headers, effectively making two different Access-Control-Allow-Origin headers.

This stops the request from being sent with the following error:
XMLHttpRequest cannot load {{ URL }}. The 'Access-Control-Allow-Origin' header contains multiple values '{{ ORIGIN }}, *', but only one is allowed. Origin '{{ ORIGIN }}' is therefore not allowed access.

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 58.0.3029.110  Channel: n/a
OS Version: OS X 10.11.6
Flash Version: 

<3
 
Labels: Needs-Milestone

Comment 2 by mkwst@chromium.org, Jun 19 2017

Components: -Blink>SecurityFeature Blink>SecurityFeature>CORS
Owner: tyoshino@chromium.org
Status: Assigned (was: Unconfirmed)
tyoshino@: Can you triage this, please?
This is working as intended.

The CORS preflight cache doesn't cache the received Access-Control-Allow-Origin directly. It processes the received Access-Control-Allow-Origin by comparing it with the current request's origin, and then saves the result to the cache to remember a certain attempt has been allowed.

Therefore, emitting a new Access-Control-Allow-Origin with non-wildcard value cannot revoke an existing cache entry.

I'm not sure what you meant by the "What went wrong?" section. Chrome doesn't remember the Access-Control-Allow-Origin value as far as inside the CORS logic. Did you really got the console message? Could you please check that your server is not sending multiple Access-Control-Allow-Origin headers?
Labels: Needs-Feedback

Comment 5 by u...@umur.io, Jun 20 2017

Sorry it wasn't clear in the initial report, replying inline:

I think it makes sense for the cache to act like that. But there might be
something going on when using the Access-Control-Max-Age header. It seemed
like it cached the wildcard, and when I changed the origin header to a
specific domain, it looked like it combined the two headers as if the
server sent two Access-Control-Allow-Origin headers.

I can confirm that I got the error and that the server was only sending one
header. Server config was my first suspect but copying the curl from
network tab had shown the server was sending the right header.

With that being said, there was a time where the server was sending two
Access-Control-Allow-Origin headers with Access-Control-Max-Age at the same
time. Could it be that Chrome cached those faulty headers?
Thanks for checking and clarification.

Regarding the error, I guess the HTTP cache, not the CORS preflight result cache has cached a response with the multiple Access-Control-Allow-Origin headers and it's passed to the CORS preflight handling logic. I think the CORS preflight algorithm was kicked again and fetched the response and printed the log using the header in it. The log is generated from the (cached) response data. Not from the CORS preflight cache. Could you please try clearing the browser's cache (just using the standard way to clear the user data) and see if it reproduces?

The Access-Control-Max-Age header determines how long the CORS preflight result cache should be used. It doesn't affect the expiration of the response in the HTTP cache.

Please also note that Chrome throws away the CORS preflight cache once the renderer process is destroyed. So, of course, it does so when the browser is terminated. On the other hand, the HTTP cache is preserved across browser restart.

Comment 7 by u...@umur.io, Jun 21 2017

Thanks!

I am fairly certain that HTTP cache was disabled as I had the network tab
open and cache disabled, the network tab also didn't show any indication
about being served from the cache (Reporting HTTP 200). That's at least my
take when it comes to Chrome's HTTP cache but I know nothing about the
internals.

Sorry I can't give more diagnostic information at this point, I will try to
get around generating an isolated and reproducible environment - but this
might take a while.
> I am fairly certain that HTTP cache ...

Oh, I see. Sorry.

Yeah, reproduction steps would really help.

Comment 9 by est...@chromium.org, Nov 10 2017

Labels: Hotlist-EnamelAndFriendsFixIt
Labels: -Hotlist-EnamelAndFriendsFixIt
Owner: ----
Status: Unconfirmed (was: Assigned)
Summary: CORS headers with max-age persist even a after changing Access-Control-Allow-Origin (was: CORS headers with max-age persist even a after changing changing Access-Control-Allow-Origin)
Waiting for repro steps.
Project Member

Comment 12 by sheriffbot@chromium.org, Feb 26 2018

Cc: tyoshino@chromium.org
Labels: -Needs-Feedback
Thank you for providing more feedback. Adding the requester to the cc list.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: Needs-Feedback
Owner: tyoshino@chromium.org
Status: Assigned (was: Unconfirmed)
assigning bug so it doesn't show up as untriaged
Cc: -tyoshino@chromium.org
Owner: toyoshim@chromium.org
Reassigning to toyoshim@ tentatively as I'm leaving the project soon.
hum... I haven't checked specs yet, but if you know...
shall we just bypass the http cache on making a preflight request? otherwise, practical max-age will be the time of 'Expires' + 'Access-Control-Max-Age' that may make developers be confused.
Labels: OOR-CORS

Sign in to add a comment