-
Notifications
You must be signed in to change notification settings - Fork 337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Origin and Access-Control-Allow-Origin to have multiple values #1790
Comments
I don't understand how this setup works with third-party cookie deprecation. Provided it somehow works, we can't change how |
Just to clarify, site1.com, site2.com, and auth.com set cookies for themselves through redirects. There is no iap.com in the view of the browser, since it is only used for resolution. There was a small error in the first flow diagram, which I fixed to clear it up. The flow that is problematic with third-party cookie deprecation is when Site 1 makes a CORS request to Site 2, requiring a third party cookie. This likely works currently because of a few reasons:
While the last two measures won’t help in the long term, and IAP architectures may need to evolve as the new PrivacyCG standards mature (eg: Partitioning target site cookies), the core issue remains: Browsers cannot properly follow redirects during a CORS request without forcing applications to rely on a wildcard Access-Control-Allow-Origin. As mentioned above, this limitation even restricts credentialed CORS redirects between subdomains within an eTLD+1 domain, which third-party cookie deprecation does not affect.
This is reasonable. Does my suggestion in the initial description help as an opt-in strategy: Add another parameter to fetch redirect “follow_cors”? Setting this would cause the browser to create Multiple Origins for the request upstream and since this is always going to be in a cross origin context, the server should be aware of the multiple origins, else it won’t set the appropriate Access-Control-Allow-Origin headers causing failure. |
I suspect so. Now in 2009 I had actually written up things as a space-separated list and Adam Barth followed that in the IETF draft: https://lists.w3.org/Archives/Public/public-webapps/2009JulSep/1267.html. However, I undid this here because implementations were not emitting a list: 713ddad. One of the URLs referenced there has this quote from Brad Hill:
So that's a case of A making a request to B which redirects to A. Today that gives |
I reached out to Brad and he provided some relevant references to this discussion:
Further, I dug into the browsers' code history to see if there was anything there:
At that point, CORS spec seems to rely on HTML5 for definition of Origin, which defines it implicitly as single valued. Piecing it together with the Firefox Origin documentation clarifies why they could have arrived at "null" for that single value. Just by reading between the lines, it doesn't seem like there was a coordinated pathway to this convergence. Instead it looks like it was driven by implementers not using multiple origins for redirects causing the vulnerability you referenced, and variations between different specifications at that point. |
Context
Identity Aware Proxies(IAP) form the core of most Zero Trust solutions including Google BeyondCorp, Cloudflare Access, Okta Access Gateway, Pomerium. An IAP is a VPN replacement that acts as a reverse proxy requiring user authorization context to allow access to the sites it fronts. It retrieves this context by requiring a user to authenticate and authorize themselves, upon which the context is created and provided to the client in the form of a cookie included with each request to the IAP.
A sample flow for user accessing site1.com fronted by an IAP is as follows:
When a user without any existing session accesses a site fronted by an IAP, the IAP requires the user to authenticate, creating an authentication session first. It then creates and sets an authorization cookie specifically for the target site. After this, if the user accesses a second site fronted by the IAP, it uses the existing authentication session and creates a new authorization cookie for the second site. Typically, the onboarded sites (Site1, Site2) have their DNS records pointed to the IAP, which proxies traffic based on the Host header or SNI. After the initial authentication, this process is completely transparent to the user. For L7 traffic, the user experience is similar to accessing target sites through a VPN in most cases.
Issue
If a user accesses Site 1 and gets a cookie set for Site 1, and then Site 1 attempts to make an Fetch/XHR request to Site 2 (which does not yet have a cookie) proxied by the IAP, this becomes an issue due to CORS. Traditionally, this scenario works seamlessly with a VPN. In this case, since the initial authentication for Site 1 creates an authentication session for the user, the browser simply needs to follow redirects to Site 2 to get a cookie set for Site 2. While Fetch/XHR requests do follow redirects, they run into CORS issues due to Origin value being set to null on redirects as follows:
An ideal flow would look like this and would remedy this situation:
* Please note that the flow diagrams include only specific headers and not all required headers
These issues have been documented over a long period of time in the IAP space, with non-standard workarounds suggested:
The workarounds so far have been:
These workarounds are useful only in limited scenarios and makes the user and application onboarding experience difficult compared to a traditional VPN.This also limits the rollout of these Zero Trust solutions due to the impact in user workflows. With the industry moving towards Zero Trust solutions, it’d be beneficial to solve this issue directly.
Potential solution
Currently, the issue is caused by cross origin redirects setting Origin value to “null”, which is done to prevent confused deputy attacks like CSRF during redirects. Unfortunately, this is causing issues in scenarios like this. I would welcome any solution that helps mitigate this issue; the easiest and most secure way to resolve this would be to allow the Origin and Access-Control-Allow-Origin headers to have multiple values. This approach will help construct a trusted path, mitigating confused deputy attacks and removing the anonymity from redirects as showcased here:
There is precedent with the original Web Origin Concept RFC mentioning this:
The CORS documentation for developers also discusses how the Access-Control-Allow-Origin header was intended to have multiple origin values:
If this could cause backwards compatibility issues, could we consider adding a new value to the redirect parameter in fetch in addition to “follow”, “manual” and “error” : “follow-cors”?
The text was updated successfully, but these errors were encountered: