Strange Behavior with CloudFront CORS requests using signed cookies and with credentials, not sending back Access-Control-Allow-Credentials unless I include some extra header

1

Hello, I'm having a very strange issue that I can't seem to crack. I configured a private CloudFront distribution to serve content from a private S3 bucket. I am using signed cookies to grant access to the files. I am also making cross origin requests from a browser for the files, so I need to allow credentials to send the cookie. I configured a custom response headers policy to do this (I set it to set Access-Control-Allow-Credentials to true, explicitly set Access-Control-Allow-Origin to my intended domain, and set Access-Control-Allow-Methods / Access-Control-Max-Age appropriately, and it is set to origin override), and I also set up a custom cache policy to cache based on origin and access-control headers.

this cURL command is not giving the correct response:

curl -v -H "origin: https://my-subdomain.my-domain.com" -H "cookie: CloudFront-Key-Pair-Id=MyKeyPairID; CloudFront-Policy=Base64EncodedPolicy; CloudFront-Signature=SignedPolicy" https://my-other-subdomain.my-domain.com/key/to/my/private/file.txt

it yields the following:

< HTTP/1.1 200 OK
< Content-Type: application/octet-stream
< Content-Length: 576
< Connection: keep-alive
< Date: Fri, 18 Feb 2022 18:34:09 GMT
< Last-Modified: Thu, 16 Dec 2021 14:45:12 GMT
< ETag: "a50884915242f9876bea4bb633963191"
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< Access-Control-Allow-Origin: https://my-subdomain.my-domain.com
< Vary: Origin
< X-Cache: Hit from cloudfront
< Via: 1.1 redacted.cloudfront.net (CloudFront)
< X-Amz-Cf-Pop: EWR50-C1
< X-Amz-Cf-Id: JxMbPWHeQr0a9AAlf9PI5ksF6xGKVWL1LvpEC9XEoR_PVuVgiJ5zGA==
< Age: 626

Notice the missing Access-Control-Allow-Credentials header.

However, this command, yields the correct response:

curl -v -H "X-some-header: nonsense" -H "origin: https://my-subdomain.my-domain.com" -H "cookie: CloudFront-Key-Pair-Id=MyKeyPairID; CloudFront-Policy=Base64EncodedPolicy; CloudFront-Signature=SignedPolicy" https://my-other-subdomain.my-domain.com/key/to/my/private/file.txt

returns:

< HTTP/1.1 200 OK
< Content-Type: application/octet-stream
< Content-Length: 576
< Connection: keep-alive
< Date: Fri, 18 Feb 2022 18:34:09 GMT
< Last-Modified: Thu, 16 Dec 2021 14:45:12 GMT
< ETag: "a50884915242f9876bea4bb633963191"
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: https://my-subdomain.my-domain.com
< Vary: Origin
< X-Cache: Hit from cloudfront
< Via: 1.1 redacted.cloudfront.net (CloudFront)
< X-Amz-Cf-Pop: EWR50-C1
< X-Amz-Cf-Id: pUSouCDwLH5Zu6-NBUZqKrb5kY407GLqXXtH4EK2-Th0Z9zZNb54ag==
< Age: 693

this time, with the correct Access-Control-Allow-Credentials header. I have no idea what I might have misconfigured to cause this or why this could be happening. Any insights would be greatly appreciated, any configuration or test output needed, just let me know.

Thank you

EDIT:

After some trial and error, I've determined the origin override setting on the Response Header Policy is causing the problem. When that is set to true, it will not send the Access-Control-Allow-Credentials header unless you send some extraneous header with your request. This is an issue as it also causes unwanted preflight requests in the browser.

Turning that setting off and then configuring my S3 Bucket's CORS to look like the below fixed it:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "https://*",
            "http://*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

However, I'm still curious if I was misunderstanding the origin override setting and there's a way to do that correctly, or if this is a bug of some kind in CloudFront

asked 2 years ago2139 views
1 Answer
-1

If Access-Control-Allow-Credentials is false, it will not display in the response headers.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/understanding-response-headers-policies.html#understanding-response-headers-policies-cors

Access-Control-Allow-Credentials – This is a Boolean setting (true or false) that determines whether or not CloudFront adds the Access-Control-Allow-Credentials header in responses to CORS requests. When this setting is true, CloudFront adds the Access-Control-Allow-Credentials: true header in responses to CORS requests. Otherwise CloudFront doesn’t add this header to responses.

profile pictureAWS
EXPERT
Chris_G
answered 2 years ago
  • I configured my response headers policy to set Access-Control-Allow-Credentials to true. As stated in my question, this works as expected if I include some random extraneous header, but does not work if I just send normal headers. That's why I can't figure this out.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions