I am trying to block hotlinking of my Cloudfront files from specific domains. Through a combination of online examples and Amazon's own policy generator, I have come up with this:
{
"Version": "2008-10-17",
"Id": "http referer policy",
"Statement": [{
"Sid": "Block image requests",
"Action": "s3:GetObject",
"Effect": "Deny",
"Resource": "arn:aws:s3:::mybucket/subdir/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://example.com/*"
]
}
},
"Principal": {
"AWS": "*"
}
}]
}
I sent an invalidation request for a file in the subdirectory of mybucket
, then a few minutes later tried reloading the image with the referer header still sent (verified using Chrome's dev tools). Did a hard reload with Ctrl+F5, and the response headers contained "X-Cache:Miss from cloudfront" so it's definitely getting the latest version of the image.
But the image is still displaying fine and is not blocked. The policy generator did not have an option for the "aws:Referer" key, but it's in the Amazon docs here. Have I done something wrong here?
Update 2
Revisiting your policy I wonder how you have actually allowed CloudFront access to your objects in the first place? Have you by chance followed the common advise in e.g. Start Using CloudFront with Amazon S3 that You must ensure that your object permissions are set to Make Everything Public for each object in your Amazon S3 bucket.
In this case you might have stumbled over a related pitfall due to the interaction between the meanwhile three different S3 access control mechanisms available, which can be rather confusing indeed. This is addressed e.g. in Using ACLs and Bucket Policies Together:
When you have ACLs and bucket policies assigned to buckets, Amazon S3 evaluates the existing Amazon S3 ACLs as well as the bucket policy when determining an account’s access permissions to an Amazon S3 resource. If an account has access to resources that an ACL or policy specifies, they are able to access the requested resource.
Consequently you would need to migrate your ACL to the bucket policy (i.e. allow CloudFront access before denying via aws:referer) and delete the overly generous ACL thereafter.
Good luck!
Update 1
Okay, now with client caching out the way, I'm afraid this is going to be non trivial (as apparent when you search for aws:referer in the AWS forums), thus might require a couple of iterations (especially given you have researched the topic yourself already):
HTTP referer
header is not necessarily going to be available, see e.g. Referer Hiding (thus your policy won't prevent malicious access anyway, though that's apparently not the issue)
The policy looks fine at first sight - before digging further into this direction though, I'd recommend to ensure that you are actually bypassing Chrome's cache successfully, which is notoriously less straight forward than people are used to from other browsers; in particular, Ctrl + F5
simply reloads the page, but does not Bypass the cache (not reliable at least)!
As documented there as well, you could use one of the other key combinations To reload a page and bypass the cache (including the confusing 2nd Ctrl + F5
after the 1st one reloaded) , however, I recommend facilitating one of the following two alternatives instead:
Ctrl + Shift + N
) keeps Google Chrome from storing information about the websites you've visited, which as of today (might change anytime of course) seems to include cached content, cookies, DNS and the like as expected, thus is an even quicker, though less explicit option right now.