Problem with Hotlink Protection

Dear all,

I am having a problem getting hotlinking protection to work. I run an
image gallery on a nginx webserver and would like to achieve that
hotlinking to the images on the website is impossible to save
bandwidth.

I have the following code in my location block:

← SNIP —>

location ~* .(png|gif|jpg|jpeg)$ {
valid_referers server_names;
if ($invalid_referer) {
return 403;
}
}

← SNAP →

That works fine so far. But the problem is that the gallery script
creates image links that look like this:

← SNIP —>

http://www.mydomain.com/image.php?twg_album=album-05900-05999&twg_show=image-05995.jpg

← SNAP →

These do not trigger the hotlink protection. I am totally lost and have
no idea how I might be able to protect those image links from
hotlinking.
Any help would be highly appreciated! Thank you all in advance!

Kind regards
-Amitz

Posted at Nginx Forum:

On Wed, Sep 14, 2011 at 11:19:05AM -0400, dullnicker wrote:

Hi there,

I am having a problem getting hotlinking protection to work.

I have the following code in my location block:

location ~* .(png|gif|jpg|jpeg)$ {
valid_referers server_names;
if ($invalid_referer) {
return 403;
}
}

That applies to locations that end in one of those four words.

http://www.mydomain.com/image.php?twg_album=album-05900-05999&twg_show=image-05995.jpg

That location ends in “.php”, since things after the ? don’t count for
location matching. And so the above config doesn’t apply, as you saw.

These do not trigger the hotlink protection. I am totally lost and have
no idea how I might be able to protect those image links from
hotlinking.

The two simplest (to me) ways of approaching it would be (a) if
/image.php
counts as “an image link”, then configure it like one – wherever in
your configuration you match this location, add the “invalid_referer”
check. (If you have something like “location ~* .php$”, and you don’t
want all matching urls to have this configuration, then copy the content
to a new “location = /image.php” and add the extra bit there);

or (b) if image.php is your modifiable script, and it has access to
HTTP_REFERER, code the protection in there yourself.

If neither of those applies, then you can probably try mucking around
with $arg_twg_show; but that feels wrong to me.

All the best,

f

Francis D. [email protected]

Dear Francis,

thank you very much indeed for taking the time to help me out. It seems
that - with your help - I made it! :slight_smile:
I inserted the “invalid_referrer” check within the “location ~* .php$”
block like you suggested and it works like a charm now!

It looks like this:
← SNIP →
location ~ .php(.*)$ {
valid_referers server_names;
if ($invalid_referer) {
return 403;
}

include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
error_page 404 /404page.html; #makes nginx return it’s default 404

page instead of a blank page

}

<–SNAP–>

Again, thank you for your fantastic help!

Kind regards
-Amitz

Posted at Nginx Forum:

On Wed, Sep 14, 2011 at 12:22:30PM -0400, dullnicker wrote:

Hi there,

thank you very much indeed for taking the time to help me out. It seems
that - with your help - I made it! :slight_smile:

You’re welcome; and congratulations :slight_smile:

I inserted the “invalid_referrer” check within the “location ~* .php$”
block like you suggested and it works like a charm now!

Good stuff.

location ~ .php(.*)$ {

Note that this config applies to all urls that include the four
characters
“.php”; that certainly includes your /image.php script, but possibly
also includes more.

If you’re happy that all of those have this invalid_referer check,
then it’s fine. If not, you’ll want to adjust the config again.

All the best,

f

Francis D. [email protected]

On 14 Set 2011 17h22 WEST, [email protected] wrote:

valid_referers server_names;
error_page 404 /404page.html; #makes nginx return it’s default 404

page instead of a blank page

I think that Francis suggestion is one that you should
consider. Restrict the referer checking to the image.php script only.

location = /image.php {
valid_referers server_names;
if ($invalid_referer) {
return 403;
}
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
error_page 404 /404page.html; # makes nginx return it’s default 404
# page instead of a blank page
}

HTH,
— appa

Thank you both! I totally agree with you, but as soon as I restrict
referer checking to the image.php script only, there is a flaw
appearing: image.php then gets downloaded by the browser instead of
displaying it. Do you have any idea why this happens? It would be great
if I could restrict the check only to this one .php file, but - as said

  • it does not work here…

Thank you again for your kind help and support,
Amitz

Posted at Nginx Forum:

On 16 Set 2011 19h47 WEST, [email protected] wrote:

Thank you both! I totally agree with you, but as soon as I restrict
referer checking to the image.php script only, there is a flaw
appearing: image.php then gets downloaded by the browser instead of
displaying it. Do you have any idea why this happens? It would be
great if I could restrict the check only to this one .php file, but

  • as said
  • it does not work here…

No I don’t. If you replicated the FastCGI stuff it should work. The
request should be sent upstream to the FastCGI listener that you have
on port 9000.

Your config had a strange thing. You used a try_files directive. That
doesn’t make sense unless you’re serving the file directly or using
another location (try_files does an internal redirect).

My suggestion omitted that. The $fastcgi_script_name variable takes as
value the $uri. In this case image.php.

If you request
http://www.mydomain.com/image.php?twg_album=album-05900-05999&twg_show=image-05995.jpg

this location is used and the request is handled upstream bu the
FastCGI process that will use image.php and whatever arguments you
give.

— appa

Please post the config you are using when it does this.