- From: Arul Thileeban Sagayam <notifications@github.com>
- Date: Thu, 05 Dec 2024 10:52:32 -0800
- To: whatwg/fetch <fetch@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/fetch/issues/1790@github.com>
### What is the issue with the Fetch Standard? ### Context Identity Aware Proxies(IAP) form the core of most Zero Trust solutions including [Google BeyondCorp](https://www.usenix.org/system/files/login/articles/login_winter16_05_cittadini.pdf), [Cloudflare Access](https://www.cloudflare.com/zero-trust/products/access/), [Okta Access Gateway](https://www.okta.com/products/access-gateway/), [Pomerium](https://pomerium.com/docs/internals/architecture). 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: ![iap_flow](https://github.com/user-attachments/assets/cb3e8c90-e2cc-43b9-a67a-1367d6bcb369) 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: ![cors_current](https://github.com/user-attachments/assets/96fb2ff5-7d95-4b76-b681-8ebc8d77a461) An ideal flow would look like this and would remedy this situation: ![cors_fixed](https://github.com/user-attachments/assets/ca0de238-5b30-4c89-bd16-ab51f516578d) \* 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: - https://developers.cloudflare.com/cloudflare-one/identity/authorization-cookie/cors/ - https://www.pomerium.com/docs/guides/cors - https://docs.banyansecurity.io/docs/securing-private-resources/hosted-websites/cors/ - https://stackoverflow.com/questions/53163761/enable-cors-with-google-iap ,https://issuetracker.google.com/issues/78326322 The workarounds so far have been: - **Ask users to access Site 2 first:** Users access Site 2 before Site 1 to ensure the cookie for Site 2 is set. - **Set a cookie across the subdomain:** Configure cookies to be shared across all endpoints fronted by the IAP, by specifying it for a subdomain instead of per site. This removes a security barrier foundational to Zero Trust principles and won’t work in cases where there are multiple subdomains involved. - **Share the cookie via a header:** Modify applications to include the cookie in headers. This adds complexity and deviates from standard practices. 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: ![cors_fixed_multiple](https://github.com/user-attachments/assets/1346eb0c-2f27-4457-9b92-7ae1eb4c44df) There is precedent with the [original Web Origin Concept RFC](https://datatracker.ietf.org/doc/html/rfc6454) mentioning this: > In those cases, the user agent MAY list all the origins in the Origin header field. For example, if the HTTP request was initially issued by one origin but then later redirected by another origin, the user agent MAY inform the server that two origins were involved in causing the user agent to issue the request. The [CORS documentation for developers ](https://w3c.github.io/webappsec-cors-for-developers/)also discusses how the Access-Control-Allow-Origin header was intended to have multiple origin values: > Although the CORS specification implies that you can list multiple origins in the Access-Control-Allow-Origin header, in practice only a single value is allowed by all modern browsers. If this could cause backwards compatibility issues, could we consider a new value to the redirect parameter in fetch in addition to “follow”, “manual” and “none” : “follow-cors”? -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/fetch/issues/1790 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/fetch/issues/1790@github.com>
Received on Thursday, 5 December 2024 18:52:36 UTC