I have a WordPress site where I'm gonna host files such as MP3s. The thing is I know if I don't do anything, MP3 Crawlers like mp3glu or mp3pleer will come and use my files and bandwidth, which I don't want (it's a free host, and since he's already kind enough to host me, I don't want to cost him too much, you know).

Now I saw that I could use the htaccess file, but... how ? I currently have this :

RewriteEngine on
#Disallow blank:
#RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?thomaskowalski.net [NC]
RewriteRule \.(jpg|jpeg|png|gif|mp3|mp4)$ - [NC,F,L]

Basically, I wanted to try to say that the pensees thing was not here anymore if the referrer was not my website itself (thomaskowalski.net). Though, it doesn't work. I created a random reddit post so my referrer should not be my site and well it works as if i had done nothing (if whatismyreferrer is right, the referrer is empty)

Any idea ? I precise that the pensees is not a file nor a directory, it's a wordpress network blog, but doing anything else (with a file for example) does the same.

Thank you in advance

  • Are you sure your .htaccess/mod_rewrite is being processed? What you have should prevent "hotlinking", by serving a 403 Forbidden. "the referrer is empty" - By following a link on another site the HTTP referer should not be empty (whatismyreferrer cannot test this?). But anyway, your current rules block an empty referer (the line is commented out). This method only prevents casual "hotlinking". If a site is determined to pull MP3s from your site then it can still do so unless you protect them with some kind of authentication (or start blocking IP addresses). – MrWhite Nov 29 '15 at 14:51
  • Anyway, the goal is to block most of it, it's not to create a super safe music store, it's just a personal blog. – Thomas Kowalski Nov 30 '15 at 18:05

I would not depend on the referrer.

The easiest way is to make a set of rules with IP addresses you want blacklisted as well as user agents you want blacklisted and if a remote user matches any of the blacklists, then they will receive the not-authorized page. Below is a template you can use. replace the set of three x's with digits for the IP address and the slashes are next to the dots to make them literal. Also, change secretmp3folder to the folder where your MP3's are stored.

RewriteEngine On
RewriteCond %{REMOTE_ADDR} xxx\.xxx\.xxx\.xxx [OR]
RewriteCond %{REMOTE_ADDR} xxx\.xxx\.xxx\.xxx [OR]
RewriteCond %{REMOTE_ADDR} xxx\.xxx\.xxx\.xxx [OR]
RewriteCond %{REMOTE_ADDR} xxx\.xxx\.xxx\.xxx
RewriteRule ^/secretmp3folder/(.*)$ - [R=403,L]

RewriteCond %{HTTP_USER_AGENT} ^badagent$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^terribleagent$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^insaneagent$
RewriteRule ^/secretmp3folder/(.*)$ - [R=403,L]

Another thing you can do is when advertising the download, make the link to it a special page that sets a cookie then redirects the user to the download.

Here's an example. (keep in mind I'm excluding common HTTP headers and I'm only showing content within the body tags)

The advertisement page:

<p>Download any of these songs</p>
<a href="download.php?mp3=song1.mp3">Song 1</a><br>
<a href="download.php?mp3=song2.mp3">Song 2</a><br>

The download.php script the links link to:

  if (intval($_GET['DOWNLOAD']) != 1){
    header("HTTP/1.1 301 Moved",true);
    header("Location: http://example.com/path/to/download.php?mp3=".$_GET["mp3"]."&DOWNLOAD=1",true);
    if (intval($_COOKIE["candownload"]) != 1){
     echo "Access denied";
    header("content-type: application/ms-download",true);
    header("content-disposition: attachment; filename=".$_GET["mp3"],true);
    echo file_get_contents("/path/to/".$_GET["mp3"]);

The script isn't 100% perfect since some things needs tweaking depending on where the MP3 files are on your system. But the idea is when someone clicks a downloadable MP3 file, they are taken to a redirect page and at the same time a cookie is stored on the clients computer to identify them as a client. then after the redirect, the client is validated as a client and the download immediately begins.

| improve this answer | |
  • Thanks for this, though, I find it a little too... too much. I mean it's just a blog where I'll sometimes put some music to the visitors to discover, it's not a music store or something, and getting all the IP addresses of the websites I don't want to let access my files seem... difficult. But if nothing else works I'll do it this way. – Thomas Kowalski Nov 29 '15 at 20:29
  • Well, looks like it's some Chrome plugin which removes the referer, on Edge whatismyreferer gets it, but it still doesn't work (see page here : reddit.com/r/draft/comments/3upiwr/test) – Thomas Kowalski Nov 29 '15 at 20:36

To stop hotlinking from any website just add this to your htaccess:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)example.com/.*$ [NC]
RewriteRule \.(gif|jpg|jpeg|bmp|zip|rar|mp3|flv|swf|xml|php|png|css|pdf)$ - [F]

more info Here

UPDATED: It worked well for me when I hosted mp4 files

UPDATED: this is what I used for my website and it seemed to work well. Other websites could not stream my videos at all. This is not just for blocking other websites to use your files. I just want to show where the bit of code you are looking goes.

Options -Indexes +FollowSymlinks

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^watch/([^/]+)/? view.php?id=$1 [NC,L]
RewriteRule ^([0-9_-]+)/?$ index.php?id=$1 [L]
RewriteRule ^([a-z-]+)/?$ search.php?q=$1 [NC,L]
RewriteCond %{THE_REQUEST} \ /search(?:\.php|)\?q=([^\ &]+)
RewriteRule ^ /%1? [L,R]

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mysite.com [NC]
RewriteRule \.(jpg|jpeg|png|mp4)$ - [NC,F,L]
| improve this answer | |
  • Gonna try this... – Thomas Kowalski Nov 29 '15 at 20:29
  • It may be a stupid question, but does this apply to the subfolders ? It's a Wordpress site, so the files are in /wp-content/uploads or something like this, not at the root where my .htaccess is. – Thomas Kowalski Nov 29 '15 at 20:32
  • There's really no difference between this code and the code posted in the question, except this code is less restrictive by allowing an empty referer. Yes, it should apply to subfolders, unless maybe you have more .htaccess files dotted around? "It's a Wordpress site" - ah, so where are you putting these directives? This will need to go before any WordPress stuff. – MrWhite Nov 29 '15 at 22:17
  • I had it just before rewrite stuff. I will update my answer because the code will look bad in this comment – StuckBetweenTrees Nov 30 '15 at 9:10
  • I updated my htaccess with the content of yours, and put it before all the WordPress stuff. Still the same :( (see here : pastebin.com/fyKJLRhe) – Thomas Kowalski Nov 30 '15 at 18:04

I once went for a solution which was simple, but effective:

// You place this in your index.php
$_SESSION['is_user'] = true;

// And this in your download.php:
if( isset($_SESSION['is_user']) ){
    // Download magic here

A crawler often doesn't set a session, and for those that do often don't store it to the next url.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.