Lokua
Lokua

Reputation: 576

S3 CORS Configuration: restricting to specific domains has no affect?

I have a bucket on S3 with everything public, and the following CORS configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>http://example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>http://localhost:3333</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

With that configuration, I would expect to only be able to get objects when requesting from http://example.com or http://localhost:3333, and receive 403s when linking to urls in that bucket from other domains. As it stands, I can still link to audio and image files in that bucket from http://dev.example.com as well as http://localhost:4444.

What am I doing wrong?

Upvotes: 2

Views: 2549

Answers (2)

sideshowbarker
sideshowbarker

Reputation: 88096

Setting the CORS configuration on a bucket isn’t on its own going to prevent anyone from being able to embed images or audio served from that bucket — and won’t otherwise cause any requests to the bucket to be denied. You can’t do that just through CORS configuration.

Browsers are where all cross-origin restrictions are enforced, and browsers allow cross-origin URLs for audio and images to be embedded in any document, regardless of CORS settings.

But by default browsers don’t allow frontend JavaScript code to access responses from cross-origin requests made with XHR or the Fetch or with Ajax methods from JavaScript libraries. That’s the only place where CORS comes in. It doesn’t affect behavior for normal cross-origin embedding of audio and images. Instead it allows you, from the server side, just to tell browsers which origins you want to unblock XHR/Fetch/Ajax requests from.

And all that your bucket does differently when configured with CORS support is just to send the Access-Control-Allow-Origin response header and other CORS response headers. That’s it.

All enforcement or relaxation of cross-origin restrictions is done by browsers on the client side — not on the server side by your bucket. In other words, as far as CORS configuration, what you set on your bucket is essentially just advisory information for browsers to use.

So no matter what CORS configuration you make on the bucket, it still goes on accepting requests from all clients and origins it would otherwise; in other words, all clients from all origins still keep on getting responses from it just as they would otherwise.

But browsers will only expose responses by your bucket to a cross-origin request from frontend JavaScript code running at a particular origin if your bucket is set to opt-in to permitting the request by responding with an Access-Control-Allow-Origin header that allows that origin.

That’s the only effect you can cause with CORS config on the bucket. You can’t just through CORS configuration make it only allow the audio or image files it serves to be embedded just by particular origins. To do that, you need to use something other than just CORS configuration.

Upvotes: 4

Ankit Kumar Rajpoot
Ankit Kumar Rajpoot

Reputation: 5600

Firstly you should have to off all public access, then You should have to set a bucket policy like this.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::013721739313:user/s3-testing-user"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::s3testingankit1/*"
        },
        {
            "Sid": "Allow get requests originating from https://z2psandbox.today/*.",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3testingankit1/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": "https://example.com/*"
                }
            }
        }
    ]
}

then set CORS

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Upvotes: 0

Related Questions