How to set CORS headers on your Amazon S3 bucket

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

The CORS standard describes new HTTP headers which provide browsers a way to request remote URLs only when they have permission. Although some validation and authorization can be performed by the server, it is generally the browser’s responsibility to support these headers and honor the restrictions they impose.

An example of a cross-origin request: The frontend JavaScript code for a web application served from http://websiteone.com uses XMLHttpRequest to make a request for http://websitetwo.io/data.json. Another example might be JavaScript that calls files in an Object Storage bucket, like web fonts, downloads etc. It is possible to configure CORS for each bucket with aws-cli.

Configuring CORS can be a challenge. In this post, we will learn how to open up your Amazon S3 bucket using CORS.

This post is targeted at static websites or files hosted on an Amazon S3 bucket.
I’m assuming you want to open up your bucket, for instance because you’re storing images that you wish to load into a canvas element, or maybe you’re storing a JSON file that you want to fetch client-side.

Of course you can adjust the settings to allow for more granular access.

Related content:

Amazon S3 Cors Settings

Let us create a policy config

{
  "CORSRules": [
    {
      "AllowedOrigins": ["https://test.citizix.com", "https://data.citizix.com"],
      "AllowedHeaders": ["*"],
      "AllowedMethods": ["GET", "HEAD", "POST", "PUT", "DELETE"],
      "MaxAgeSeconds": 3000,
      "ExposeHeaders": ["Etag"]
    }
  ]
}

Note that this opens up the bucket to access from the listed domains – [“https://test.citizix.com”, “https://data.citizix.com”]. If you want to open it completely, with no restrictions on origin, use :

"AllowedOrigins": ["*"]

This means everyone will be able to get at your data.
You have to decide whether this is appropriate for your use case!

The easiest way to update your CORS policy at Amazon is using the AWS CLI tool.

In order to do so, store the above snippet in a JSON file, s3-cors.json, and run the following:

aws s3api put-bucket-cors \
    --profile my-aws-profile \
    --bucket my-bucket \
    --cors-configuration file://s3-cors.json

Alternatively, you can do this from the AWS Console.
Log into your account, find your bucket, and look for the Permissions tab. Find the heading Cross-origin resource sharing (CORS), and there you can paste your CORS rules.

Getting the CORS configuration of a bucket

To retrieve the CORS rules of a bucket, use aws-cli:

aws s3api get-bucket-cors --bucket BUCKETNAME

If CORS rules are set for the bucket, the API returns a JSON list like this example:

➜ aws s3api get-bucket-cors --bucket my-bucket
{
    "CORSRules": [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "GET",
                "HEAD",
                "POST",
                "PUT",
                "DELETE"
            ],
            "AllowedOrigins": [
                "https://test.citizix.com",
                "https://data.citizix.com"
            ],
            "ExposeHeaders": [
                "Etag"
            ],
            "MaxAgeSeconds": 3000
        }
    ]
}

If there are no CORS rules set for the bucket, an error message appears:

An error occurred (NoSuchCORSConfiguration) when calling the GetBucketCors operation: The CORS configuration does not exist

Verifying the CORS configuration of a bucket

To verify the CORS rules of a bucket, curl can be used with the different methods (GETPOST, …)

For example:

curl -X OPTIONS -H 'Origin: http://MY_DOMAIN_NAME' http://BUCKETNAME.s3.eu-west-1.amazonaws.com/index.html -H "Access-Control-Request-Method: GET"

Deleting the CORS configuration of a bucket

To delete the CORS rules of a bucket, use aws-cli:

aws s3api delete-bucket-cors --bucket BUCKETNAME

CloudFront

One common configuration is to use CloudFront to serve your bucket contents behind a custom domain, using SSL.

Header forwarding in particular can cause quite a bit of head scratching, since it’s not always clear why your carefully constructed CORS rules are still not being picked up by the browser!

When using CloudFront, you have to whitelist all headers that you want forwarded to the origin.
In particular, for our example, the following headers are required:

  • Origin
  • Access-Control-Request-Method
  • Access-Control-Request-Headers

Having whitelisted these headers, you’re all set up and your client-side code will finally be able to fetch() your content.

CloudFront Response Header Policies

Note that CloudFront also offers the option of attaching Response Header Policies to a distribution. In that way you can configure CORS headers completely independent of the bucket, which might suit your use case better.

Last updated on Mar 20, 2024 16:36 +0300
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy