Cross-Origin Resource Sharing (CORS) is a mechanism that uses HTTP headers to grant a web application running on one origin permission to reach selected resources in a different origin. The web application executes a cross-origin HTTP request when it requests a resource that has a different origin from its own, including domain, protocol, or port.
When you protect a site with Cloudflare Access, Cloudflare checks every HTTP request bound for that site to ensure that the request has a valid authentication cookie. This has implications for CORS configurations, including:
To handle CORS headers for the policy protecting the path that requires CORS, navigate to the bottom of the Create Access Policy window and expand the Advanced settings section and configure the settings.
Access-Control-Allow-Credentials allows CORS headers or methods to use the user’s credentials to reach the protected application or path.
Access-Control-Max-Age (seconds) allows you to set a maximum time for caching the results of a CORS request.
Access-Control-Allow-Origins lets you list the fully qualified domain name (FQDN) that makes the CORS request. You can add multiple FQDNs or select Allow all origins to permit any FQDN.
Access-Control-Allow-Methods allows you to permit all method types (for example, POST or GET requests).
Access-Control-Allow Headers allow you to permit all HTTP headers or HTTP headers you define that meet the criteria defined in the Access-Control-Allow-Origins or Access-Control-Allow-Methods sections.
You can use the command-line tool
curl to review your configuration. To do so, you will need three prerequisites:
curl command below includes all three.
curl -I -XOPTIONS https://app2.site.com \ -H 'origin: https://app1.almightyzero.com' \ -H 'access-control-request-method: GET'
If configured, Cloudflare will return a response similar to the following example:
HTTP/2 200 date: Wed, 22 Apr 2020 18:17:44 GMT set-cookie: __cfduid=d886c3e5dd7b8c4daba5f9f0cd173c3511587579464; expires=Fri, 22-May-20 18:17:44 GMT; path=/; domain=.almightyzero.com; HttpOnly; SameSite=Lax vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers access-control-allow-origin: https://app1.almightyzero.com access-control-allow-methods: GET access-control-allow-credentials: true expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 588157e55e0882d7-ATL cf-request-id: 0244b54354000082d7b991f200000001
Cross-origin requests that do not require a specific OPTIONS preflight are common known as Simple Requests. The browser will still require the correct CORS headers, but will not send a preflight OPTIONS request to retrieve them. To make one of these requests, the
CF_authorization cookie must be included. CORS configurations made in the Cloudflare Access dashboard will not be applied; these CORS headers must come from the origin.
Requests that do not include the cookie will be redirected to the Cloudflare Access login page.
In general, we recommend the following steps when troubleshooting CORS issues:
credentials: 'same-origin'in all fetch or XHR requests.
If you have two sites protected by Cloudflare Access,
app2.hostname.com, requests made between the two will be subject to CORS checks. Users who login to
app1.site.com will be issued cookies for
app1.site.com and your Cloudflare Access authentication domain.
When the user's browser requests
app2.hostname.com, the cookie will not be present for that domain so the request will be sent to the login page. However, the user will have a cookie for their Cloudflare Access session, which will redirect them successfully to
app2.hostname.com if they are permitted to reach it.
During this entire flow, the browser itself will check CORS headers. As part of that behavior, the browser will make the
Origin header null once a 302 has occurred. Cloudflare Access honors all redirects, however, the final redirect of a login will be made to the original domain. Since the
Origin header is still null, unless the configuration allows all origins, the request will now fail due to the browser's CORS issue. A refresh will resolve this for the user.
This can be addressed with the following settings:
nullas an allowed origin.
Safari, in particular Safari 13.1, handles cookies in a unique format. In some cases, this can cause CORS to fail. This will be dependent on Apple releasing a patch for handling cookies. This is known to impact macOS 10.15.4 when running Safari 13.1 (15609.1.20.111.8).
CORS checks do not occur on the same domain. If this error occurs, it is likely the user flow is making a sub-request without the cookie.