Skip to content

What is best practice to block hotlinking images from Cloudfront?

0

I have a real problem with images on my site being hotlinked by others.

On 22 June (until 22 July), I followed the AWS guide to stopping hotlinking from working, which used referers. And it worked brilliantly - look, an obvious cut in the amount of bytes I was transferring from 22 June. Great!

A nice drop

All of a sudden, I was serving a lot of 40x errors and this is brilliant, I'm delighted with this. I am the server ninja! You will fall before me!

40x errors

Except, um, the number of requests to Cloudfront went up insanely high.

Requests

...and it seems that they were all the 403 Forbidden error that I'd carefully set up.

40x requests

...so by following AWS's article, yes, I ended up paying more than $130 in additional Cloudfront requests. Genius. Well done me. (I'm a little irritated, but, hey ho).

I suspect that the 403 Forbidden response wasn't sending any caching advice, so instead of the 403 being cached, it was resulting in a new request every time. And because Cloudfront charges per request, and I'd cleverly changed from about 2M to about 10M requests, I was being handsomely charged for it.

Sigh.

So. What is the best way to block these images from hotlinking on Cloudfront? Is it possible to cache a 403 Forbidden message? What else could I have done?

2 Answers
1

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

EXPERT
answered a year ago
EXPERT
reviewed 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.

0

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.

EXPERT
answered a year ago
  • 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.)

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.