Is AWS S3 CORS policy at file level?
Asked Answered
H

1

9

I'm trying to apply a CORS policy to my S3 bucket, and what I am observing is that, if at any point of time, I modify the CORS policy, the older files that were uploaded to S3 still do not use the new CORS policy. For e.g.

  1. I created a S3 bucket "X"
  2. Added the following CORS policy -

    <CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>https://app1.example.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <ExposeHeader>ETag</ExposeHeader>
        <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>
    
  3. Successfully uploaded a file a.jpeg from my application that is hosted on https://app1.example.com. I was also able to do a GET and a DELETE.

  4. Now I need to use the same S3 bucket for another one of my hosted apps, say app2. So I modified the CORS policy to -

    <CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>https://app1.example.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <ExposeHeader>ETag</ExposeHeader>
        <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://app2.example.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <ExposeHeader>ETag</ExposeHeader>
        <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>
    
  5. Now when I try to GET the file a.jpeg from https://app2.example.com, I still see the below error

    XMLHttpRequest cannot load <S3 URL>. Origin https://app2.mydomain.com is not allowed by Access-Control-Allow-Origin.
    
  6. However if I try to upload a new file b.jpeg from https://app2.mydomain.com, everything works as expected.

EDIT

I forgot to mention this earlier, but we have a CloudFront CDN in front of our S3 bucket, but I cannot find any config related to setting CORS policy in the Cloudfront config.

Is there a way by which we can enforce the new CORS policy on previously uploaded files as well? Or is there some other way to make this work?

Hatfield answered 8/7, 2015 at 18:17 Comment(6)
Used protocol:// instead of https:// coz I wasn't being allowed to post more than 2 links with below 10 reputation.Hatfield
Try surrounding those https strings with ` backticks, with an edit, please. That should cause them to be interpreted as opaque string literals instead of links. Also "example.com" is preferred, since I assume the domain you've used isn't your actual domain, and may be somebody else's.Depth
S3 CORS policy is bucket-level... but S3 also supports a single wildcard in the allowed origin (e.g. *.example.com)... but is it possible your browser cached the preflight response from before the change was made? Can you capture the response headers S3 is actually returning?Depth
Thanks @Michael-sqlbot, I've modified the description as you suggested. Our security team doesn't approve of using wild cards for supported domains and each domain must be added separately. I tried doing the same flow as I have described in private browsing mode, and I still see the same issue. So I doubt that it is related to browser caching.Hatfield
Aha... CloudFront. docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/… ...The docs are a little vague on what happens if you do nothing, but it seems like to me you'd want to forward Origin: and the other two headers to S3.Depth
I got the Cloudfront config reviewed and we are already forwarding the Origin header.Hatfield
U
0

CORS headers are part of the cached response in CloudFront -- so while you may be setting them at a bucket level, only new objects are seeing it. The cached objects need to expire before they'll exhibit the new headers.

Consider either invalidating your CloudFront cache (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html) or setting your TTL much lower to force CloudFront to refresh the object from S3 within a reasonable timeframe.

Unfounded answered 12/6 at 18:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.