Cross-Origin Resource Sharing (CORS) in Amazon S3

CORS is a web browser secruity that allows you to enable images, files or assets to be retrieved from one S3 bucket incase the request is originating from a another origin.
Cross-Origin Resource Sharing (CORS) in Amazon S3 allows you to specify who can access your resources in a different domain (cross-origin) and how. This is especially useful for web applications that need to request resources stored in an S3 bucket from a domain different from where the application is hosted.

See my previous post that details how CORS works

Key Concepts of CORS in S3

  1. Origin: The domain from which a web page is served.
  2. Cross-Origin Request: A request for a resource (like an image, font, or API data) from a different domain, protocol, or port than the one the current document originates from.
  3. Browser: The application, such as a browser, that is making the request.
  4. CORS Configuration: A set of rules that define the interaction between the browser and the cross-origin server (S3 in this case).

Configuring CORS for an S3 Bucket

To enable CORS for an S3 bucket, you need to configure a CORS policy for the bucket. This policy is a JSON document that specifies which origins can access the bucket, which HTTP methods can be used, and other settings.

Example CORS Configuration

Here’s an example of a CORS configuration for an S3 bucket that allows GET requests from any origin and allows specific headers in the request:

Explanation:

  • AllowedOrigins: Specifies which origins are permitted to access the bucket. ["*"] means all origins are allowed.
  • AllowedMethods: Specifies the HTTP methods that are allowed for cross-origin requests. Common methods include GET, POST, PUT, DELETE.
  • AllowedHeaders: Lists the headers that can be used in the actual request.
  • ExposeHeaders: Specifies which headers are exposed to the browser.
  • MaxAgeSeconds: Indicates how long the results of a preflight request can be cached.

Scenario where the HTML files are in one bucket and image assets are in another bucket

Let’s walk through a scenario where a web application hosted in one S3 bucket needs to load images stored in another S3 bucket, and we need to configure CORS to allow this interaction.

Scenario Overview

  1. Bucket 1 (bucket1.example.com): Hosts the web application with the index.html file.
  2. Bucket 2 (bucket2.example.com): Stores image assets needed by the web application.

Steps to Configure CORS

  1. Set up the S3 buckets:
  • Ensure both S3 buckets are created (bucket1.example.com and bucket2.example.com).
  • Upload the index.html file to bucket1.example.com.
  • Upload image assets (e.g., image1.jpg, image2.jpg) to bucket2.example.com.
  1. Enable static website hosting on bucket1.example.com to serve the index.html file.
  2. Configure CORS policy for bucket2.example.com to allow requests from bucket1.example.com.

CORS Configuration for bucket2.example.com

To allow cross-origin requests from bucket1.example.com, you need to add a CORS configuration to bucket2.example.com. Here is an example CORS configuration:

Setting Up the CORS Policy

  1. Open the Amazon S3 Console.
  2. Select bucket2.example.com.
  3. Go to the Permissions Tab.
  4. Edit CORS Configuration:
  • Scroll down to the “Cross-origin resource sharing (CORS)” section.
  • Click “Edit” and enter the JSON configuration above.
  • Save the changes.

Example index.html in bucket1.example.com

Create an index.html file that references the images stored in bucket2.example.com:

How It Works

  1. User Accesses the Web Application:
  • The user opens a browser and navigates to http://bucket1.example.com/index.html.
  1. Browser Requests index.html:
  • The browser sends an HTTP request to bucket1.example.com to retrieve the index.html file.
  1. index.html References Images in bucket2.example.com:
  • The index.html file contains <img> tags that reference images stored in bucket2.example.com.
  1. Browser Makes Cross-Origin Requests:
  • When the browser attempts to load the images from bucket2.example.com, it detects that these requests are cross-origin (since the origin is bucket1.example.com).
  1. CORS Preflight Check (if needed):
  • If the request includes non-simple requests (e.g., with custom headers), the browser will first send a preflight OPTIONS request to bucket2.example.com.
  1. CORS Headers Validation:
  • bucket2.example.com responds with the appropriate CORS headers, indicating that requests from http://bucket1.example.com are allowed.
  • The response includes Access-Control-Allow-Origin: http://bucket1.example.com, indicating that the browser can proceed with the actual image requests.
  1. Images Loaded Successfully:
  • The browser receives the images from bucket2.example.com and displays them as specified in the index.html file.

Security Considerations

  • Least Privilege: Restrict AllowedOrigins to specific domains (http://bucket1.example.com) instead of using a wildcard (*).
  • Allowed Methods: Only allow necessary HTTP methods (GET in this case).
  • Minimize Exposed Headers: Only expose headers that are necessary for your application.

By following these steps, you enable a secure and functional cross-origin resource sharing setup between two S3 buckets, allowing a web application hosted in one bucket to access and display images stored in another bucket.

    Leave a Comment

    Your email address will not be published. Required fields are marked *

    Scroll to Top