How do I set up CORS on Amazon S3 to allow only approved domains to access a JS script in my S3 bucket? Currently, I have CORS set as follows on my S3 bucket:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="/">
<CORSRule>
<AllowedOrigin>www.someapproveddomain</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Yet any domain can access and run script hello.js
(which resides in the S3 bucket) as demonstrated at JSFiddle. Does anyone what I'm doing wrong? Or, maybe I'm just misunderstanding what CORS is supposed to do?
How do I set up CORS on Amazon S3 to allow only approved domains to access a JS script in my S3 bucket? Currently, I have CORS set as follows on my S3 bucket:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws./doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>www.someapproveddomain.</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Yet any domain can access and run script hello.js
(which resides in the S3 bucket) as demonstrated at JSFiddle. Does anyone what I'm doing wrong? Or, maybe I'm just misunderstanding what CORS is supposed to do?
- 1 Change the CORS www.someapproveddomain. to someapproveddomain. and see if it is taking effect – Piyush Patil Commented Jul 20, 2016 at 17:27
-
CORS allows scripts run in other origins to read a resource on your origin. Executing a script does not require that a cross-origin script be able to read the script. (Compare to images: you can display a cross-origin
<img>
on your page without having a script read the contents of the image.) – apsillers Commented Jul 20, 2016 at 17:47 - "CORS allows scripts run in other origins to read a resource on your origin". Hmm... According to MDN (developer.mozilla/en-US/docs/Web/Security/…): "Cross-origin reads are typically not allowed". – Bob Arlof Commented Jul 20, 2016 at 20:08
2 Answers
Reset to default 6Instead of trying to solve this with CORS, you need to solve it using an S3 Bucket Policy that restricts access to a specific HTTP referrer. This is documented here.
This is the example bucket policy given by AWS:
{
"Version":"2012-10-17",
"Id":"http referer policy example",
"Statement":[
{
"Sid":"Allow get requests originating from www.example. and example..",
"Effect":"Allow",
"Principal":"*",
"Action":"s3:GetObject",
"Resource":"arn:aws:s3:::examplebucket/*",
"Condition":{
"StringLike":{"aws:Referer":["http://www.example./*","http://example./*"]}
}
}
]
}
Note that the HTTP referrer is fairly easy for an attacker to spoof.
I do think you're misunderstanding CORS. (Edit: which is okay!)
CORS isn't intended for server-side security.
There are much better explanations here on SO than what I can explain, but one of the main purposes of this is to prevent someone from creating a fake site (like a banking portal) and having it make requests to the real server with the user's real credentials. If the server and real site have CORS enabled, the server will only allow requests from the real site's domain.
What you probably want to look into is using IAM policies or S3 bucket policies. There's an excellent blog post from AWS here that goes over this. You'll need to have an EC2 instance as a sort of middle-man to access the S3 bucket and server the files to a client.
There may be another way to do this with purely S3, but essentially if its accessible publicly without authentication, someone can technically spoof the headers to make it appear like its ing from your CORS defined domain.