S3 Cross-origin Resource Sharing (S3 CORS)
Behind the scenes, modern web applications must communicate with a large number of servers serving end users, including the servers where the website is hosted (same origin) and the external server from which the website requests additional resources (different origin). By default, the web browser's security policy only permits requests from the same origin, blocking requests from other origins, making it impossible for websites to successfully load resources from different origins. The solution to this problem is to enable Cross-Origin Resource Sharing (CORS), which enables the loading of resources from external origins. In this article, we will learn how to configure CORS to allow access to the AWS S3 resources.
The mechanism known as Cross-Origin Resource Sharing (CORS) allows modern web browsers to allow the loading of resources requested from external servers or origins.
Any web application may occasionally need to load resources from an S3 bucket, but because this is a cross-origin request to the web application server, the request may by default be denied.
While S3 is a great object storage service that offers features to address many object data storage challenges, it becomes equally crucial to set up CORS on an S3 bucket.
For resources requested from an S3 bucket to be quickly loaded into the requester's web browser, a CORS configuration needs to be configured on an S3 bucket.
To set up CORS on an S3 bucket, we must first create a CORS configuration that specifies the rules for determining which origins are permitted access to the S3 bucket and its objects. The cross-origin resource-sharing rules in an S3 CORS configuration can number up to 100. The S3 CORS configuration can be created in JSON format using the AWS S3 console.
Consider the following example to understand the CORS configuration where PUT, POST, and DELETE methods are allowed from cross-origin requester www.scaler.com:
The following parameters can be used in an S3 CORS JSON configuration, as demonstrated by the example above:
- AllowedMethod Element The AllowedMethod element in the CORS configuration supports the following HTTP methods GET, PUT, POST, DELETE, and HEAD.
- AllowedOrigin Element We list the origins from which we want to accept cross-domain requests in the AllowedOrigin element, for example, http://www.scaler.com.
- AllowedHeader Element Through the Access-Control-Request-Headers header, the AllowedHeader element specifies which headers are permitted in a preflight request. The wildcard character * will allow all headers.
- ExposeHeader Element The header in the response that users can access from their applications is identified by each ExposeHeader element.
- MaxAgeSeconds Element The MaxAgeSeconds element specifies the amount of time in seconds that your browser can cache the response.
How to Configure CORS?
Follow these steps on the AWS S3 console to configure AWS S3 CORS:
Go to the AWS S3 console and choose the required bucket from the list of buckets.
Select Permissions, then click Edit in the Cross-origin resource sharing (CORS) section.
Enter the S3 CORS configuration in the CORS configuration editor text box.
Select Save changes.
Alternatively, AWS SDKs available in different languages and REST APIs can be also used for programmaticallyy configuring AWS S3 CORS.
Example Use Cases of CORS in S3
The following use cases can be considered for configuring AWS S3 CORS:
- One use case for loading static content from an S3 bucket is when a website requests some static resources to be loaded. If CORS is not configured on S3, the website may not be able to load the resources.
- Requests made via the S3 API from a website to a bucket can also be regarded as one of the use cases where an API call could fail if CORS is not enabled on the S3 bucket.
- Web fonts can be loaded from an S3 bucket, and if CORS isn't enabled, browsers may reject requests to load web fonts.
Evaluation of CORS Config on an S3 Bucket
The first CORS Rule rule that matches the incoming browser request is used by Amazon S3` to enable a cross-origin request when it receives a preflight request from a browser and analyses the bucket's CORS configuration.
- An AllowedOrigin Element must match the Origin header of the request.
- One of the AllowedMethod Elements must be present in the request method or the Access-Control-Request-Method header in the case of a preflight OPTIONS request.
- On the preflight request, each header listed in the Access-Control-Request-Headers header must correspond to an AllowedHeader Element.
The following methods can be used to troubleshoot any unexpected behavior of S3 CORS:
- Check to see if the bucket's CORS configuration is set.
- Log the complete Request and Response log and analyze them to find the root cause.
- Make sure the Origin header is present in the request.
- Make sure at least one of the AllowedOrigin elements in the given CORSRule matches the Origin header in your request.
- Make sure the method in your request is one of those listed in the same CORSRule's AllowedMethod element.
- Check that the CORSRule contains the AllowedHeader entries for each value in the Access-Control-Request-Headers header for a preflight request if the request contains the Access-Control-Request-Headers header.
- By default, the web browser's security policy only permits requests from the same origin. Cross-Origin Resource Sharing (CORS`) enables the loading of resources from external origins.
- The cross-origin resource-sharing rules in an S3 CORS configuration can number up to 100.
- The configuration can be created in JSON format using the AWS S3 console.
- The JSON configuration consists of the following parameters, AllowedMethod, AllowedOrigin, AllowedHeader, ExposeHeader, and MaxAgeSeconds.
- Browsers may reject requests to load web fonts from an S3 bucket if CORS isn't enabled. Requests made via the S3 API from a website to a bucket can also fail. IfCORSis not configured on S3, the website may not be able to load the resources.
- Log the complete Request and Response log and analyze them to find the root cause. Make sure the Origin header is present in the request. Check that the method in your request is one of those listed in the same CORSRule's AllowedMethod element to troubleshoot a failing S3CORSrequest.