How the code to prevent hotlinking works
1 <?php
2 $dir='secret-directory-name-here/';
3 if ((!$file=realpath($dir.$_GET['file']))
4 || strpos($file,realpath($dir))!==0 || substr($file,-4)=='.php'){
5 header('HTTP/1.0 404 Not Found');
6 exit();
7 }
8 $ref=$_SERVER['HTTP_REFERER'];
9 if (strpos($ref,'http://www.example.com/')===0 || strpos($ref,'http')!==0){
10 $mime=array(
11 'jpg'=>'image/jpeg',
12 'png'=>'image/png',
13 'mid'=>'audio/x-midi',
14 'wav'=>'audio/x-wav'
15 );
16 $stat=stat($file);
17 header('Content-Type: '.$mime[substr($file,-3)]);
18 header('Content-Length: '.$stat[7]);
19 header('Last-Modified: '.gmdate('D, d M Y H:i:s',$stat[9]).' GMT');
20 readfile($file);
21 exit();
22 }
23 header('Pragma: no-cache');
24 header('Cache-Control: no-cache, no-store, must-revalidate');
25 include($file.'.php');
26 ?>
Line 2
Line 2 stores the name of secret directory so that the script can easily be modified.
Lines 3 to 7
On line 3, the first condition of the if-test checks that the file exists and resolves any relative path components (for exmaple ../). On line 4, the second condition checks the the path specified is in the secret directory (so that people can’t use relative path components to see the source code of scripts on your site), and the third condition checks that the path does not refer to one of the PHP files associated with the content. If the file specified should not be accessed (or doesn’t exist) a 404 (file not found) status code is returned and the script exits.
Lines 8 and 9
The if-test in line 9 could have been written in various forms, but using the ‘or’ operator with this order of parameters is fastest. The test allows the file to be displayed if either the referrer header does not refer to a website (for example, a blank refer or one obscured by security software), or if it refers to the correct wesbite. The slash at the end of the website name is necessary to prevent exploitation by websites with names of the form
http://www.yoursite.com.theirsite.com/), and the use of ‘http’ in the second condition catches both regular (http://) and secure (https://) referrers.
Lines 19 to 21
These lines output the content file with the appropriate headers for content type, content length, and date of last modification, and then exit the script.
Lines 23 to 25
These lines output headers to prevent caching and then perform the action specified in the PHP file associated with the content file (for example, redirecting to the page containing the content). The anti-caching headers are needed so that if users later try to view the content as you intended they will receive the content file and not the HTML file. Note that the content file itself will be cached, which means that if a site hotlinks to the file and a user already has the file in their cache they will still see it. If they don’t already have the file in their cache, their browser will download an HTML file, which it will realise isn’t a media file and won’t display (unless the link was a direct link, rather than a hotlink).
For more ready-to-use examples of this kind, try O’Reilly & Associates’ excellent PHP Cookbook:
PHP Cookbook at Amazon.com
PHP Cookbook at Amazon.co.uk (for British readers)
original
http://www.safalra.com/programming/php/prevent-hotlinking/