I'm trying to protect my images from hotlinking. My first approach was this:

location ~* \.(png|jpg)$ {
    valid_referers none blocked server_names;
    if ($invalid_referer) {
        return 403;

The problem here is the none tag, because if you enter a url directly there is no referer. So every website could still show my images if a user enters the url directly. So i removed the none tag and surprisingly it's still working on my website.

If I enter my url directly it's still working. But why?

Now my referer is empty but I can still see my images. It definitely works because of the server_names tag but as far I understand the server_names means that if someone has my server name in the referer they could show my images. But If I enter my URL directly I don't have a referer.

Can someone explain this to me?


This is well explained in the documentation for valid_referers:

  • none

    the Referer field is missing in the request header;

  • blocked

    the Referer field is present in the request header, but its value has been deleted by a firewall or proxy server; such values are strings that do not start with http:// or https://;

  • server_names

    the Referer request header field contains one of the server names;

It behaves just like it's supposed: none allows the request without any referer and server_names the referers matching your server names.

This setup is for preventing hotlinking i.e. embedding of your images on other sites. It's not supposed to prevent viewing of the images if you know the URL for example if you look for it on the source of the page.

Also, you have to think of the usability of your site in the first place. After all, you merely want to make a statement to someone using your images on their pages, not to the one actually viewing them. Some browsers or firewalls may remove the referer, making the images to disappear even on your own site when not allowing the none.

If you'd like to be really strict, which I don't recommend, you wouldn't rely on the referer at all. Instead, you could set a limited time cookie on your page and check for the presence of that cookie when trying to access images.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.