Search code examples
phpapache.htaccessmod-rewritehotlinking

Hotlink Protection not working with .htaccess


I have WordPress MU installed on the server and using some Mod Deflate and Caching the files and some other minor amendments in the .htaccess file and when I came across some modification for the clients, I noticed that on his server the images are served from my server.

Server Config: Plesk/CentOS - Linux Hosting

After a full research I tried placing all the available codes in the StackOverflow articles and other tutorials and sites but can't find what am doing wrong but it's not working.

.htaccess with the hotlink regex and other rewrite rules

RewriteEngine On
RewriteRule ^index\.php$ - [L] 

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]
RewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]
RewriteRule . index.php [L]

<Files wp-config.php>  
       order allow,deny  
       deny from all  
</Files> 

<Files .htaccess>  
   order allow,deny  
   deny from all  
</Files> 

<Files xmlrpc.php>
Order allow,deny
Deny from all
</Files>

# Wordfence WAF
<Files ".user.ini">
<IfModule mod_authz_core.c>
    Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
    Order deny,allow
    Deny from all
</IfModule>
</Files>

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?domain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]

If I empty my .htaccess and just keep the following code it works.

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?domain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]

What am I doing wrong?


Solution

  • You need to keep this HTTP_REFERER above all other rules. Problem is that you have rule that is rewriting all URIs to index.php. Due to that rule RewriteRule \.(jpg|jpeg|png|gif)$ fails.

    Complete .htaccess:

    RewriteEngine On
    
    RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?domain.com [NC]
    RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
    
    RewriteRule ^index\.php$ - [L] 
    
    # uploaded files
    RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
    
    # add a trailing slash to /wp-admin
    RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]
    RewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]
    RewriteRule . index.php [L]
    
    <Files wp-config.php>  
           order allow,deny  
           deny from all  
    </Files> 
    
    <Files .htaccess>  
       order allow,deny  
       deny from all  
    </Files> 
    
    <Files xmlrpc.php>
    Order allow,deny
    Deny from all
    </Files>
    
    # Wordfence WAF
    <Files ".user.ini">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order deny,allow
        Deny from all
    </IfModule>
    </Files>