Welcome to WebmasterWorld Guest from

Forum Moderators: Ocean10000 & incrediBILL & phranque

Message Too Old, No Replies

Denying direct access to .jpg



1:04 am on Jan 15, 2009 (gmt 0)

10+ Year Member


I'd like to prevent someone from linking to my .jpg images.

Not HOTlinking. I know how to do stop hotlinking.

I want to stop, plain, direct linking. Linking directly to my images.

How to do this in .htaccess?



1:38 am on Jan 15, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

Use a script to serve the image, set a cookie on the page of your site that is authorized to include that image, and have the script check for the cookie before serving the image.

All referrer-based methods will fail, because HTTP referer headers are not required, can be easily spoofed, and won't be sent by corporate or ISP caching proxies or by browsers behind "internet security" software.

The only part that .htaccess can play in this scheme is to rewrite requests for the image to the script described above.



2:36 pm on Jan 15, 2009 (gmt 0)

10+ Year Member

It's only one particular webmaster that bypasses my website by linking to .jpg's directly.

I can't serve a 403 to a direct request? Seems to me it would be the simplest solution, if it's possible.


5:25 pm on Jan 15, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

It is not possible if the only information you have to identify him is the HTTP referer header. If this 'other webmaster' types in the URL directly or accesses it using a bookmark, the referrer header will be blank. If he uses internet security software or connects to your site through a corporate caching proxy or a caching proxy inside his ISP's network (as used by AOL, EarthLink, etc.) then even if he accesses the image by clicking on a link, the HTTP referer header may be blank.

You cannot rely on the HTTP referer header being present or correct, so it is useless for anything except stopping *most* hotlinking -- Even when used for anti-hotlinking purposes, it only works most of the time, because users behind caching proxies or who have internet security software may not send a referer header as described above, and in order for your site to work with type-ins, bookmarks, IE JavaScript object references, and corporate or ISP-deployed caching proxies, you *must* allow blank-referer requests. Otherwise, your site will look broken to all of these users. Note that search engines won't normally send a referer header, either.

If this other webmaster always connects to your server using the same IP address, then you could block his requests based on his IP address. However, if his ISP assigns IP addresses from a 'pool' of IP addresses, then you risk blocking other users in that pool, and he can probably change his IP address simply by power-cycling his modem.



8:42 am on Jan 16, 2009 (gmt 0)

10+ Year Member

It's possible. You could even disallow direct hit to the jpg's URL. I`ve email you the source of the code.


2:35 pm on Jan 16, 2009 (gmt 0)

5+ Year Member

Use perl or php or asp to server images. Something like example.com/showimages.php?hash=hash-value

Use has to determine refer and expire urls. Lighttpd web server has inbuilt support to stop such linking which uses format




2:36 pm on Jan 16, 2009 (gmt 0)

5+ Year Member

(0) put the images in a directory outside of the webserver's scope

(1) set a cookie from the page that is going to contain the images.

(2) pass the name of the image file to a php script that will check for the presence of the cookie before outputting the image.

to get a copy of the script, search for "chill : prevent hot linking without reliance on javascript or referer"


4:09 pm on Jan 16, 2009 (gmt 0)

10+ Year Member

I'm probably missing something, but I think this may be getting more complicated than it needs to.

As I understand it the OP is concerned that someone posts a link to his images on their website, that people can click on and view directly in their browser.

If I understand this correctly wouldn't just blocking by referrer (based on the domain(s) the other webmaster is using) be adequate? The vast majority of the other webmaster's users are not going to be messing with their referrer so the image will be blocked for them, which makes it useless from the other webmaster's point of view.

The only problem with that I can see is if the other guy starts playing games to prevent his users passing a referer, but he may not have the technical knowledge, time or inclination to do so. If he does then a cookie based system could be implemented if necessary.


4:46 pm on Jan 16, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member

So the user is creating links in their web page that people can click on to load your images? Then you'd have to block them by IP address.

But is this in the nature of the internet? Can't anyone link to any of our publicly available data without our permission?

If they are using the links for inflammatory purposes then I'd contact their ISP.


4:55 pm on Jan 16, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

It is not an issue of users "messing with their referrer" -- In most cases, people whose referrers get "messed" have no idea that it is happening. The OP states that he knows how to do "regular anti-hotlinking" so the implication is that those methods are not adequate in this case.

All referrer-based methods have a big hole in them, because blank referrers must be allowed so that your site does not look broken to people who type in your address, use a bookmark, use an ISP which uses in-network caching proxies to reduce out-of-network traffic (such as all AOL and Earthlink subscribers), or who are using "internet security" software which blocks the Referer header -- either with or without the user's knowledge. If JavaScript is used to load images on your site, then IE won't send a referrer when doing so either. So blank referrers must be allowed unless you want your own site to look broken to these users.

At the same time, some portion of users --the ones whose referrers are blocked-- will bypass your anti-hotlinking measures, and they will see the hotlinked images on the other site's pages.

Referrer-based anti-hotlinking with blank referrers allowed is therefore only a "usually good enough" solution, in that people who do not site behind caching proxies or use internet security software which blocks the referrer will see broken images on the hotlinking sites. Some of them will complain via e-mail or by posting comments in blogs or on forums. This represents a "hassle" to the hotlinking site's Webmaster, which is often enough to get him to quit hotlinking.

In cases where the hotlinking webmaster is not paying attention or his users don't complain, then 'creative' solutions can be used, such as serving an alternate image. Some webmasters like to get tricky and serve 'objectionable' images, impugning the hotlinking site's reputation. Others like to serve an image with an embedded (image) link to their own site, so as to possibly recover some traffic in exchange for the bandwidth otherwise wasted on serving the hotlinked images.

But the bottom line is that referrer-based anti-hotlinking solutions are only partially-effective because blank referrers must be allowed. So for more obstinate cases, the image-serving-script-and-cookie method is called for, as I stated in my first post and echoed by later posters.

I should probably add that when testing anti-hotlinking code or any server-side access-control-code, it's important to completely flush your browser cache between tests, or to temporarily disable it by setting the cache size or cache expiry time to zero. Otherwise your browser will cache the image (or the 403-Denied response) and serve it to you from cache on subsequent requests without sending any request to your server. Since no request is sent to the server, your server-side access-control code won't have any effect, confusing your test results.



8:55 pm on Jan 16, 2009 (gmt 0)

5+ Year Member

jdMorgan has it pretty well covered, but I'm contending that the image-serving-script-and-cookie method is also unreliable; while it may absolutely prevent hotlinking, legitimate users of your site who have cookies disabled will be unable to see any images.

Given the number of people who have cookies disabled at this point in history, it may not be a huge problem, but it's a problem regardless. My recommendation beyond that would be a Session variable; however, since those can rely on cookies as well (you could pass the Session ID via the querystring when necessary, but I've never liked this option for security reasons), you may want to try yet another approach.

I would write a file to the server; it's contents would be a timestamp of the last actual page request, the name of the file would be based on the IP address or some other unique client identifier. When a request for a PAGE comes in, update the file's timestamp. When a request for an IMAGE comes in, check the timestamp value in the file. If it's more than fifteen minutes old, 403 it. Make sure the Image Serving Script does not update the timestamp and you should be fine.

The only problem I can envision occuring with that is that several people using the same proxy could request images indefinitely (more accurately, for as long as someone was browsing the site in question on that proxy). And that's assuming it's based exclusively on IP address.

Another method would be specifying a random hash at the start of every page and loading every image referencing this hash (stored on the server, of course). Any given hash could effectively be valid for one page only (another querystring variable? &bLast=true erases the hash...). Change it every hour, every day, every page request; whatever floats your boat.

Also, for a bit of fun with the image serving script, you could use mod_rewrite in your .htaccess file to disguise the fact that you're using an image serving script. This would also make it infinitely easier to switch a massive site over to this method, assuming it didn't use an image-serving script before.


11:48 pm on Jan 16, 2009 (gmt 0)

5+ Year Member

Agreed referrer isn't perfect.

How about using the image css hack to detect if the user has ever visited the other website.

Also, you could assign each image a token that's only valid for a short time. All other links would have to be served with new token, so it might not work if all the links that are ok are not within your control and on php/asp pages.


10:13 am on Jan 19, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member

You could use PHP to generate each page and rewrite the names of the images on a daily basis. Anyone trying to link to them would soon get fed up with broken links. Eg:

day 1: flower.gif (PHP also rewrites the links to match)
day 2: floral.gif
day 3: petals.gif

Or in the extreme:

day 1: gXij73.gif
day 2: lMug6H4.gif

Yes, a random filename would be best so the same word didn't come up twice.


3:48 pm on Jan 19, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member

i remember reading somewhere that you can insert php code directly into an image.
the example that i saw was a little line inserted at the end calling the php info page.
if you could do that, then presumably you could use the image itself to check for the referer.
that way no one would ever work out why it's not working.


7:59 pm on Jan 19, 2009 (gmt 0)

5+ Year Member

You can in fact configure other files to be parsed by PHP before being served to a client; it's more common to do this with, say, a .html extension (to retain SEO value on an old site being upgraded) as opposed to an image. Setting this up will vary depending on your server configuration, but suffice it to say you need to parse the image/jpeg (or what have you) MIME type.

However, this A) would probably break all of your images (such that you could not edit them, unless it's a gif and you placed the code after the data), B) would require you to apply the necessary changes to each and every image, and C) does NOT fix the Referer issue.

As jdMorgan put it, HTTP_REFERER is, quite frankly, unreliable at best. Some clients may not provide it, and some clients may provide false information. There's also no way to confirm if the information is valid, so you can't opt to use it only when it's valid.


10:17 pm on Jan 19, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member

if you serve the images through a php script, then you only have to check that the script is being called from your own website. you don't have to check for the user's referrer.

totally reliable.
(assuming that you keep the images outside of your root)


11:24 pm on Jan 19, 2009 (gmt 0)

10+ Year Member

It's only one particular webmaster

And what about contacting him (friendly)? Many people do things because they don't know better - they think it's ok to put copyright protected content on their website (while they don't know that this is not permitted by law).
May be this webmaster doesn't know that direct deep links to your images are undesired?


8:18 pm on Jan 20, 2009 (gmt 0)

5+ Year Member

londrum, how do you presume to test where the script is being called from without checking the referer? The script itself will always be executing on your server; what we need to know is where was the client when they made this request?


To be clear, the only way to check where a script or file was called from is the HTTP_REFERER header, which, as has been repeated countless times, is unreliable. Beyond that, we can only get the client's information.

Again, to be clear, the Client is not going to be the offending website, it's going to be the person who is reading that website.

As it goes, when the client's browser sees <img src="http://www.some.sit/imgsrvr.php?img=test.gif" /> it posts a GET request to some.sit for imgsrvr.php, which is then parsed by the server and the output is sent back to the browser. If the browser is playing nicely, it adds the HTTP_REFERER header to that GET request, filled in properly with the URL of the page that told it to download your image.


10:49 pm on Jan 20, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member

oh right, yeah, the penny has dropped now.

why not try the old school way of putting the offending webmaster off.
change one of your images to a horrendous, outrageous #*$! picture (after changing the filename on your own site, of course), and then emailing him to tell him what you've done.
tell him you'll carry on changing a pic at a time, but this is the last time that you're going to email him to warn him.

actually, i've just had a thought about my inserting php code into an image idea...
maybe you only have to do it for ONE image, rather than all of them.

if you can get him to serve that image on his site (after swapping it out for another image on your own site), then couldn't you get it to do something when it shows on his site? it would still be running through the php script on your own site.


3:47 pm on Jan 21, 2009 (gmt 0)

5+ Year Member

That is one way of doing it, and it is what the internets is best at.

To answer your question, it won't allow you to do anything special. You can change the contents of the image before you write it as output, but that's nothing special. Again, you ultimately have the just end-user's information to work with, no info about what site is referencing your stuff; also again, there is no benefit to embedding the code directly in the images (especially if you remove them from the root directory of your site).

Also, we're talking about PHP, which is a decidedly server-side scripting language. That means YOUR server-side.


1:56 am on Jan 31, 2009 (gmt 0)

5+ Year Member

From what I gather, you don't want the offending website sending his visitors straight to the image (example.com/example1.jpg). It is possible to redirect visitors trying to access the .jpg file to the webpage that hosts it.

You should have
example.com/example1.jpg redirect a visitor to
example.com/mywebpage1.html or even better

example using mod_rewrite:

RewriteEngine on

RewriteRule ^/me.jpg$ stopdirectlinking.php