- Newest
- Most votes
- Most comments
Hi,
This blog post (a bit old) proposes a solution based on AWS WAF: https://aws.amazon.com/blogs/security/how-to-prevent-hotlinking-by-using-aws-waf-amazon-cloudfront-and-referer-checking/
This articles also proposes a solution leveraging AWS WAF: https://habil.dev/hotlink-protection-with-aws-waf-cloudfront/
Starting point for WAF: https://aws.amazon.com/waf/
Best,
Didier
The request fees are charged by both CloudFront and WAF for both cached and uncached objects, including errors. If your scale is sufficiently high, you could use Shield Advanced to avoid per-request fees for WAF, paying only for outbound gigabytes instead, but the request fees for CloudFront would still be charged. Your scale would have to be large enough to warrant the fixed fee for Shield Advanced, but since it's only paid for once for an entire AWS Organizations org, large enough scale can make it worthwhile.
In the perhaps unlikely case that a substantial portion of the requests would be coming from search engines, servers of social media sites, or countries where you have no business interests, you could consider pointing those origins instead of your CloudFront distribution to an ALB just returning a 403 or 500 fixed response based on the requesters' IP addresses (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-ipbased.html) or geolocation (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-geo.html). Geo-restrictions you could also configure in CloudFront: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html. That would reduce the likelihood of those clients hitting your CloudFront+WAF setup at all, but I realise this isn't going to help, if the hot-linked images are being loaded directly by end users in your primary operating regions.
You could also try serving 404 responses instead of 403s and serving a generous max-age Cache-Control value in them. I'm not sure if that will make a difference, but it might avoid reload attempts by clients refused access.
Thanks, Leo. Shield Advanced is $3,000 a month, and given I'm trying to avoid this extra $130 a month bill, that's not quite for me!
For another block rule, I've added "Vary: Origin" and a generous Cache-Control value, which may, at least, ensure that the devices (TV set top boxes, by the looks of things) cache the request internally. I'll monitor those effects, and see if they helped.
(What I'd like to do - but can't - is to serve a small image file in the body of the 403 Forbidden error. It seems content-type isn't able to be changed.)
Relevant content
- asked 4 years ago
- AWS OFFICIALUpdated a year ago

The blog post you point to is the one I used, as I documented. The second one is devoid of any detail whatsoever (and won't help the issue).
The issue isn't that I wasn't successful in blocking. I was. The issue is that it made the number of requests rocket - and by following AWS documentation, I've cost my business more than $130.