Valid_referers directive not working correctly

I am trying to block all requests which do not come from my own server.
A
quick read of the nginx wiki led me to the valid_referers directive. I
implemented it like:

server {
listen 80;

server_name ~^(?.+).my-domain.io$;

root /srv/www/accounts/$account/app;

index index.php;

access_log /var/log/nginx/accounts/$account/access.log;
error_log /var/log/nginx/accounts/error.log;

include /etc/nginx/excludes.conf;
include /etc/nginx/expires.conf;

location / {
valid_referers server_names not-my-domain.com;
if ($invalid_referer) {
return 403;
}

location ~\.php {
  try_files $uri =404;
  fastcgi_index index.php;
  fastcgi_intercept_errors on;
  fastcgi_pass 127.0.0.1:3001;
  include /etc/nginx/fastcgi_params;
  fastcgi_param MY_DOMAIN_ACCOUNT $account;
}

}

I purposefully put not-my-domain.com instead of my-domain.com to make
sure a
403 status code was returned. Unfortunately, it is not. I wrote a simple
html file with an iframe that grabs a php page from the server from a
different domain. This should be returning a 403 code, but it works.

Any ideas? Thanks.

Posted at Nginx Forum:

On Monday 12 November 2012 13:03:49 justin wrote:

if ($invalid_referer) {
}

}

I purposefully put not-my-domain.com instead of my-domain.com to make sure
a 403 status code was returned. Unfortunately, it is not. I wrote a simple
html file with an iframe that grabs a php page from the server from a
different domain. This should be returning a 403 code, but it works.

Any ideas? Thanks.

Your request to php page is processed in “location ~.php” which do not
have any
referrer constraints.

wbr, Valentin V. Bartenev

Ahh right, so basically I have to copy:

valid_referers server_names not-my-domain.com;
if ($invalid_referer) {
return 403;
}

Into the php match block. Is there a way to do this without having the
same
exact code copied into both location blocks?

Posted at Nginx Forum:

On Nov 12, 2012, at 13:19 , justin wrote:

Ahh right, so basically I have to copy:

valid_referers server_names not-my-domain.com;
if ($invalid_referer) {
return 403;
}

Into the php match block. Is there a way to do this without having the same
exact code copied into both location blocks?

You have to copy only

if ($invalid_referer) { return 403; }

The issue is that while the most nginx directive are declarative and
and can be easy inherted, the “if”, “rewrite”, “set”, and “return” are
imperative directives.


Igor S.

On Monday 12 November 2012 13:19:23 justin wrote:

Ahh right, so basically I have to copy:

valid_referers server_names not-my-domain.com;
if ($invalid_referer) {
return 403;
}

Into the php match block. Is there a way to do this without having the same
exact code copied into both location blocks?

You can put it on the server level.

Basically there are two types of rewrite rules:

  • “server” level
  • “location” specific

For details, see:
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

wbr, Valentin V. Bartenev

http://nginx.org/en/donation.html

Very strange, moving the directive into the server block, now blocks
everything, including requests from my own server.

valid_referers server_names *.my-domain.io;
if ($invalid_referer) {
return 403;
}

Strange that when the code was copied twice into the / location bllock
and
php match block it worked.

Posted at Nginx Forum: