Conditional blank referrer with Nginx

In this article, we’ll be showing a common use case of the referrers in the Nginx configuration and cover a use case from the real-life project our teams worked on. The task at hand is to allow a blank referrer in a scenario when a specific user-agent (Android device) makes an HTTP request – a conditional blank referrer with Nginx.

Pre-requirement: Nginx installed.

Specification:

OS Version: CentOs 8.2 x64
Nginx Version: nginx/1.14.1

What is the HTTP referrer used for

When we want to make sure that traffic is not being drained by crawlers, scrapers, etc. (although, this is a much harder task than presented here and requires a more detailed approach to protecting online content) we’d usually want to define allowed domains from which the request should be passed through. Since this might have been a mouthful, let’s simply like this:

  • when we open a website our browser fills in the page with images and other content
  • images and other static content come from somewhere (it can be the same server the website is on or some other location) by the browser “calling in” this content in order to render the page
  • when the browser makes these requests for necessary content it passes information about the domain from which the requests were made (in this case the domain of the website in question)
  • finally, a server that is supposed to be serving these files (images for example) returned the content and we got our page fully rendered

Now, let’s imagine that (and this is a real-life scenario) we want to make sure that only visitors of our website have the right to use the bandwidth needed to transfer all the images, etc. To do this, using Nginx, we can define something called “valid_referrers” and list the allowed domains (or just a single domain):

valid_referers bluegrid.io;
		if ($invalid_referer) {
			return 403;
		}

Edge case

Now, the edge case we are covering is when there’s an expected scenario where a specific user-agent can access the content even without a referrer at all – a blank referrer. The blank referrer scenario happens when a device accesses content directly, without a proxy, website, or other means of being passed from another domain.

What we need to do is check if the traffic comes from the expected user-agent and bypass the valid_referrers directive:

location / {
		set $check "1";
		if ($http_user_agent ~ (Android)) {                                  
			set $check "0";
		}
		if ($http_referer ~ ^$) {                                  
			set $invalid_referer $check;
		}
		valid_referers bluegrid.io;
		if ($invalid_referer) {
			return 403;
		}

Test solution

Test access with valid referrer:

~$ curl -I storage.bluegrid.io/ --referer https://bluegrid.io

HTTP/1.1 200 OK

Test access with the blank referrer and expected user-agent:

~$ curl -I storage.bluegrid.io/ -A "Android"

HTTP/1.1 200 OK

CURL without referrer and without user agent:

~$ curl -I storage.bluegrid.io/

HTTP/1.1 403 Forbidden

Ivan Dabić

A man with a beard and glasses, wearing an orange hoodie and a black cap with a Hard Rock Cafe logo, stands with his arms crossed against a plain white background.

Ivan Dabić

Co-founder and CEO of BlueGrid.io, with a background in cloud infrastructure, distributed systems, monitoring, and security operations. He works closely with engineering teams to build and operate reliable systems while documenting both technical and organizational aspects of modern engineering work.

Ivan is a metalhead, and big fan of cyberpunk move genre. If you are his secret Santa go with Star Wars Lego box!

Share this post

Share this link via

Or copy link