Filtering QUERY_STRING with back references in RewriteCond

183 views Asked by At

I have a PHP script used to process images before displaying them on the web page. The query string has to be checked to reject all requests coming from external domains. If TLD is example.com

http://example.com/process.php?img=somepath/images/imgX.png OK
http://example.com/process.php?img=http://example.com/anotherpath/folder/images/imgX.png OK
http://example.com/process.php?img=http://anotherdomain.com/images/someimg.jpg Rejected!

This rewrite rules work on my test server:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http://
RewriteCond expr "! %{QUERY_STRING} -strmatch '*%{HTTP_HOST}*'"
RewriteRule .* - [F]
</IfModule>

But on the production server this doesn't work. After some headaches and searching I found that expr is not supported before Apache 2.4...
From what I read I can use atomic back-references to check if the %{HTTP_HOST} is present in the %{QUERY_STRING}. The idea is to construct something like this

RewriteCond %{HTTP_HOST}::%{QUERY_STRING} ^(.*?)::/\1/?

Which obviously doesn't work in the current state. Any help and further explanation on this syntax will be greatly appreciated.

2

There are 2 answers

6
anubhava On BEST ANSWER

You can use this rule in Apache 2.2:

RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http://
RewriteCond %{HTTP_HOST}#%{QUERY_STRING} !^([^#]+)#.*?\1
RewriteRule ^ - [F]

\1 is back-reference for HTTP_HOST

Modified the RewriteCond to

RewriteCond %{HTTP_HOST}#.*#%{QUERY_STRING} !^([^#]+)#.*?\1

This captures any URL structure. JF

1
cjhill On

If you wanted to do this in PHP land then you can use parse_url.

Link to PHP documentation.