Prevent nginx from serving content to external domains (hotlinking)

Written by - 0 comments

Published on June 4th 2014 - Listed in Linux Unix Internet


Imagine you have a web server with an application and containing some static files which you only want to serve for visitors of your application. You also want to prevent that external domains can embed your pictures (hotlink) in their websites. This is where the nginx parameter "valid_referers" comes to play.

Scenario:
- Application running on under domain "app.example.com"
- There is a static file (an image) called "image.jpg"
- The image can only be displayed through the domain "app.example.com"

The following nginx config (residing within the 'server' definition) takes care of the rule:

server {
[...]
  server_name app.example.com;
[...]
  location ~* (\.jpg|\.png)$ {
    valid_referers none app.example.com;
    if ($invalid_referer) {
        return 410;
    }
  }
}

Let's explain this config snippet piece by piece:

location: Defines a location for all requests ending with .jpg or .png.
valid_referers none: All requests without a http referer will be treated as a valid referer (allowed). This is typically when your own application embeds the picture with a relative path (/image.jpg). Direct URL access also have no referer.
valid_referers app.example.com: All requests coming from "app.example.com" as referer are treated as valid and are allowed.
the if clause: All other referers/sources are treated as invalid and nginx will return a http status 410 (gone).

Now how does that work in a practical example?
Let's open a browser and go to http://app.example.com/image.jpg. The image is shown in the browser and the nginx access log shows the following entry:

1.2.3.4 - - [04/Jun/2014:10:17:24 +0200] "GET /image.jpg HTTP/1.0" 200 114557 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0"

I now created a test page on my own domain (www.claudiokuenzler.com) and embedded the picture with the img tag:

cat nginx-test/test.php

Opened www.claudiokuenzler.com/nginx-test/test.php in the browser and the picture was not shown:

Nginx valid_referers test 

The nginx access log meanwhile shows this new entry:

1.2.3.4 - - [04/Jun/2014:10:17:35 +0200] "GET /image.jpg HTTP/1.0" 410 0 "http://www.claudiokuenzler.com/nginx-test/test.php" "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0"

See the status code 410 in the log? Yes, it is working!


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.