Nginx Image Hotlink Protection: Configuring Whitelists and Blacklists

nginx hotlink protectionnginx referer whitelistnginx referer blacklistprevent image theftnginx security configuration
Published·Modified·

Sometimes you may find that other websites are directly using your site's images, causing extra consumption of server traffic and bandwidth. If your server's bandwidth and traffic are already limited, hotlinking will inevitably have an impact. This article shares how to set up hotlink protection with Nginx to prevent other websites from stealing your images.

Hotlink Protection Principle

The principle of hotlink protection is quite simple. The current popular approach is to use the Referer header for judgment and restriction. The explanation of Referer is as follows:

HTTP Referer is part of the header. When a browser sends a request to a web server, it generally includes the Referer, telling the server which page the request came from. The server can use this information for processing. — Quoted from Baidu Baike

Simply put, if my blog domain is xiaoz.me, I can configure Nginx to only allow requests with a Referer of *.xiaoz.me to access images, and block all others. Here we need to use the ngx_http_referer_module module and the $invalid_referer variable. See the following explanation for further details.

ngx_http_referer_module Module

The ngx_http_referer_module module is used to block access to the site for requests where the "Referer" header field has an invalid value. It should be remembered that it is very easy to construct requests with appropriate "Referer" field values, so the intended purpose of this module is not to completely block such requests, but to block the bulk of traffic sent by regular browsers. It should also be considered that even for valid requests, regular browsers may not send the "Referer" field.

  • Syntax: valid_referers none | blocked | server_names | string ...;
  • Used in: server, location

You can see that the valid_referers directive contains some parameters, such as none | blocked, with the following meanings:

  • none: The "Referer" field is missing in the request header, meaning the Referer is empty. When a browser accesses directly, the Referer is generally empty.
  • blocked: The "Referer" field appears in the request header, but its value has been deleted by a firewall or proxy server; these values are strings that do not start with "http://" or "https://".
  • server_names: Server names, which is a list of domain names.

$invalid_referer Variable

After setting the valid_referers directive, the result is passed to a variable $invalid_referer, which has a value of 0 or 1. You can use this directive to implement hotlink protection. If the value of the Referer header is not included in the valid_referers list, $invalid_referer will be set to 1.

Setting Up a Hotlink Protection Whitelist

A whitelist means only allowing access from domain names within the whitelist, and blocking all others.

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|webp)$ {
    valid_referers none blocked *.xiaoz.me *.xiaoz.top;
    if ($invalid_referer) {
        return 403;
    }
}

The meaning of the above configuration is to first match the required formats (images and videos) using location, then use the valid_referers directive to set the allowed domain names. Other domain names not included in the valid_referers list will cause the $invalid_referer variable to return 1, ultimately returning 403 to block access. This is the setup for hotlink protection whitelists.

Hotlink Protection Blacklist

A blacklist is the opposite of a whitelist; it only blocks requests from domain names in the blacklist and allows all others. Compared to whitelists, blacklists are more permissive. Most online tutorials only mention setting up hotlink protection whitelists. After understanding the principle, the setup method for blacklists is similar.

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|webp)$ {
    valid_referers *.baidu.com;
    if ($invalid_referer = 0) {
        return 403;
    }
}

In the above configuration, we use the valid_referers directive to set the blacklist domain *.baidu.com. After obtaining the specified Referer header, the $invalid_referer returns 0, ultimately returning 403 to block access from the Baidu domain.

Summary

Above is the setup for Nginx hotlink protection (whitelists and blacklists). After understanding the principle, it is actually very simple. However, since Referer can be arbitrarily forged, the above method cannot intercept forged Referer requests, but it is still effective for most common scenarios. If your server's bandwidth and traffic are already limited, it is recommended to add hotlink protection settings.

If you are interested, you can also read my other article: Nginx Common Blocking Rules to Make Your Website Safer

This article partially references: