graphql-engine icon indicating copy to clipboard operation
graphql-engine copied to clipboard

HASURA_GRAPHQL_CORS_DOMAIN with wildcard subdomain is not working

Open TeoTN opened this issue 2 years ago • 5 comments

Version Information

Server Version: 2.1.1

Environment

OSS

What is the expected behaviour?

Based on the example described in docs I would expect that providing wildcard for subdomain in HASURA_GRAPHQL_CORS_DOMAIN would work.

Keywords

HASURA_GRAPHQL_CORS_DOMAIN

What is the current behaviour?

When I deploy Hasura with following values:

HASURA_GRAPHQL_CORS_DOMAIN="https://*.example.pages.dev/,https://hasura.example.com,http://localhost:3000"

And load frontend making requests to the hasura instance from https://subdomain.example.pages.dev, then CORS error is thrown:

Access to fetch at 'https://hasura.example.com/v1/graphql' from origin 'https://subdomain.example.pages.dev' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

However, deploying Hasura with concrete values will resolve the issue:

HASURA_GRAPHQL_CORS_DOMAIN="https://subdomain.example.pages.dev/,https://hasura.example.com,http://localhost:3000"

It would be nice if Hasura handled setup with wildcards, since CloudFlare Pages makes preview deployments of frontend available at various subdomains.

How to reproduce the issue?

See above for reproduction steps

TeoTN avatar Apr 03 '22 16:04 TeoTN

@TeoTN We run into an intermittent issue with our site that uses Cloudflare pages calling Hasura and getting CORs issues. You ever find a solution for this? What's weird is most of the time it works but then gets into a weird state where every request ends us a 403 with xxx has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

johnkoehn avatar Jul 15 '22 21:07 johnkoehn

Server Version: v2.31.0-cloud.1 Environment: Cloud

Also running into the same issue, with given configuration

HASURA_GRAPHQL_CORS_DOMAIN="https://*.example.com"

an OPTIONS request with origin https.example.com does not return any CORS headers but a request with origin https://*.example.com returns the correct CORS headers.

Could it be that the code handling the CORS header matching is doing exact matches instead of treating wildcards properly?

This is the command I'm using to replicate

httpie \
  OPTIONS \
  https://{{my-hasura-cloud-instance}}.hasura.app/v1/graphql \
  Access-Control-Request-Headers:authorization,content-type \
  Access-Control-Request-Method:POST \
  Cache-Control:no-cache \
  Origin:https://*.example.com \
  --pretty=all \
  --print hH

zqureshi avatar Aug 09 '23 10:08 zqureshi

@TeoTN can you trying changing the value for the env to:

HASURA_GRAPHQL_CORS_DOMAIN="https://*.example.pages.dev,https://hasura.example.com,http://localhost:3000"

(removed the trailing slash from https://*.example.pages.dev/)

Hasura does support wildcards in CORS policy, so it should work.

paritosh-08 avatar Feb 13 '24 13:02 paritosh-08

@zqureshi I am not sure why you were not able get it working. I tried it on one of my hasura cloud project () and it worked as expected. I used curl for this:

curl -verbose --location --request OPTIONS 'https://<my-cloud-subdomain>.hasura.app/v1/graphql' \
--header 'Content-Type: application/json' \
--header 'x-hasura-admin-secret: <my-super-secret>' \
--header 'Origin: https://*.example.com' \
--data '{"query":"query MyQuery {\n  author {\n    name\n  }\n}\n","variables":{}}'

I got the following response (which had the CORS headers):

*   Trying <hasura-cloud-ip>...
* Connected to <my-cloud-subdomain>.hasura.app (<hasura-cloud-ip>) port <<hasura-cloud-port> (#0)
....
< access-control-allow-origin: https://*.example.com
< access-control-allow-credentials: true
< access-control-allow-methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
< access-control-expose-headers: X-Hasura-Query-Cache-Key,X-Hasura-Query-Family-Cache-Key,Warning
< cf-cache-status: DYNAMIC
< content-security-policy: upgrade-insecure-requests
< referrer-policy: strict-origin-when-cross-origin
...
* Connection #0 to host <my-cloud-subdomain>.hasura.app left intact
Click here for the full response
*   Trying <hasura-cloud-ip>...
* Connected to <my-cloud-subdomain>.hasura.app (<hasura-cloud-ip>) port <<hasura-cloud-port> (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=hasura.app
*  start date: May 10 00:00:00 2023 GMT
*  expire date: May  8 23:59:59 2024 GMT
*  subjectAltName: host "<my-cloud-subdomain>.hasura.app" matched cert's "*.hasura.app"
*  issuer: C=US; O=Cloudflare, Inc.; CN=Cloudflare Inc ECC CA-3
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x565016ed9eb0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> OPTIONS /v1/graphql HTTP/2
> Host: <my-cloud-subdomain>.hasura.app
> user-agent: curl/7.81.0
> accept: */*
> referer: rbose
> content-type: application/json
> x-hasura-admin-secret: <my-super-secret>
> origin: https://*.example.com
> content-length: 72
> 
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* We are completely uploaded and fine
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 204 
< date: Tue, 13 Feb 2024 14:06:57 GMT
< content-type: text/plain charset=UTF-8
< access-control-max-age: 1728000
< access-control-allow-headers: 
< access-control-allow-origin: https://*.example.com
< access-control-allow-credentials: true
< access-control-allow-methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
< access-control-expose-headers: X-Hasura-Query-Cache-Key,X-Hasura-Query-Family-Cache-Key,Warning
< cf-cache-status: DYNAMIC
< content-security-policy: upgrade-insecure-requests
< referrer-policy: strict-origin-when-cross-origin
< strict-transport-security: max-age=31536000; includeSubDomains
< x-content-type-options: nosniff
< x-frame-options: SAMEORIGIN
< x-xss-protection: 0
< server: cloudflare
< cf-ray: 854da2893a0ef40d-BOM
< 
* Connection #0 to host <my-cloud-subdomain>.hasura.app left intact

paritosh-08 avatar Feb 13 '24 14:02 paritosh-08

@johnkoehn, Can you please give me more information about the state when the requests fail? Please get some traces of the request sent to the graphql-engine.

paritosh-08 avatar Feb 13 '24 14:02 paritosh-08

I'm experiencing the same issue. For some reason it doesn't work when there is a - or _ in the URL. I'm using the Cloud environment as well:

Config: HASURA_GRAPHQL_CORS_DOMAIN=https://*.foobar.pages.dev,https://*.foo-bar.pages.dev

No hyphen:

curl -verbose --location --request OPTIONS 'https://heimdall.hasura.app/v1/graphql' \
--header 'Content-Type: application/json' \
--header 'Origin: https://foo.foobar.pages.dev'
< HTTP/2 404
...
< access-control-max-age: 1728000
< access-control-allow-headers:
< access-control-allow-origin: https://foo.foobar.pages.dev
< access-control-allow-credentials: true
< access-control-allow-methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
< access-control-expose-headers: X-Hasura-Query-Cache-Key,X-Hasura-Query-Family-Cache-Key,Warning

With hyphen:

curl -verbose --location --request OPTIONS 'https://<my-cloud-subdomain>.hasura.app/v1/graphql' \
--header 'Content-Type: application/json' \
--header 'Origin: https://foo.foo-bar.pages.dev'
...
< HTTP/2 404
...
< content-security-policy: upgrade-insecure-requests
< referrer-policy: strict-origin-when-cross-origin
<
...
Not Found%   

liuhenry avatar Mar 30 '24 19:03 liuhenry