I have looked around on Google and StackOverflow for the answer to this question, but the fact that I don't know much about .htaccess doesn't help me decide what the correct answers for my situation are, so I am asking here.
My situation is that I have several sites that are using the same physical directory as their root on the server.
This is all working fine but I wanted to make sure that each site can't access each others images etc from the browser unless they are on the correct domain.
Currently I have a file structure like this:
/resources/{resource}/{full_domain_name}
So for example www.domain.co.uk
would have a structure like this:
http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg
But if www.domain_2.co.uk
exists using the same physical directory for the site root then they can look at other domain's resources from their own domain, like this:
http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg
This isn't really a major problem since there is absolutely no sensitive information stored in these directories, but it's more of an annoyance and I would rather users were not able to do it (not that anyone actually has so far).
I tried putting a .htaccess file into the /resources directory but I'm stuck with the regular expressions etc.
I basically want to make sure that the URI contains the current domain name otherwise redirect to a 403 error page.
This is what I came up with:
RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$
RewriteRule ^(.*)$ /error/403.php
The reason I put in the [^/]
bit is because there are several folders, for example:
/resources/images/{full_domain_name}
/resources/scripts/{full_domain_name}
/resources/stylesheets/{full_domain_name}
Could anybody help me with these conditions?
Any help would be appreciated.
This is terrific question and if I could I would have upvoted 10+ times. I am posting my answer even though you have an accepted answer here as I really had to dig through all my Apache resources to come up with the answer. Here is the rule you will need for this problem:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC]
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE]
PS: Since we cannot use %
variables on RHS as back-reference, I am using special regex back-reference variable \1
in the RewriteCond
here.
This condition is insufficient:
RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$
Because if I request anything that doesn't start with /resources/
, I'll get the 403.php error page. What you really want is something like this:
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{HTTP_HOST} !%1
Or
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/
Where the first condition is checking that the request is for a resource, then the second checking the host. HOWEVER, neither of these will work because mod_rewrite's RewriteCond
directive doesn't allow % variables or backreferences in the right hand side of the condition, only the left. Likewise, you cannot do this either:
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php
Because the RewriteRule's expression cannot have variables in it, since it's a regex, and it literally expects a %{HTTP_HOST}
instead of replacing it with the Host given in the request. So to conclude, no, you can't do this with mod_rewrite's conditions this way.
Something that you can try if you have access to either server config or vhost config is to create a RewriteMap and pass in both the %{REQUEST_URI}
and %{HTTP_HOST}
. So if your map is called check_host
then your rule may look something like this:
RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}}
And your script will just need to parse the input, split it from the first _
, parse the request URI and make sure the host is the same as the HTTP_HOST. If it's the same, output the same request URI, otherwise output the error URI. If you don't have access to server or vhost config, I think you're out of luck. RewriteMap cannot be defined in the htaccess file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With