2

In my Apache config I'd like to return 403 when a query string parameter contains a specific value. Everything works fine except when the client query string is encoded in hex. How do I get it to match without having to type out the literal hex string?

RewriteEngine On RewriteCond %{QUERY_STRING} mykey=myval [NC] RewriteRule .* - [F,L] 

Then test it:

# Works fine, returns 403 curl -I 'http://localhost/?mykey=myval' # Does not work, returns 200: curl -I 'http://localhost/?mykey=%6d%79%76%61%6c' curl -I 'http://localhost/?%6d%79%6b%65%79=%6d%79%76%61%6c' 

thx

1 Answer 1

3

The QUERY_STRING server variable remains %-encoded (as it is in the request), unlike the URL-path matched by the RewriteRule pattern, which is %-decoded.

However, on Apache 2.4 you can use an Apache expression with the RewriteCond directive to URL decode the QUERY_STRING before making the comparison. For example:

RewriteCond expr "unescape(%{QUERY_STRING}) =~ /mykey=myval/" RewriteRule ^ - [F] 

This will now successfully match requests of the form ?mykey=myval, ?mykey=%6d%79%76%61%6c and ?%6d%79%6b%65%79=%6d%79%76%61%6c.

You don't need the L flag when using F, since it is implied. The regex ^ is marginally more efficient than .* if you simply need to be successful for any URL-path (without actually matching anything).

Note that the regex mykey=myval matches that string anywhere in the query string, so it would successfully match anymykey=myval and mykey=myvalany, which may or may not be a problem. To remove that ambiguity and only match the "key=value" pair in the query string then you would need to use a regex like (?:^|&)mykey=myval(?:&|$) instead.

Sign up to request clarification or add additional context in comments.

2 Comments

Very good use of expr directive
You're an Apache ninja, thx :) I'm curious, did the developers have a rationale for keeping the query string %-encoded for this scenario as opposed to RewriteRule having %-decoded? I realize keeping the value unescaped is the "true" value, but some "dummy proof" safeguards for web admins could help millions of people. Common scenario: site admin wants to block access to a URL and isn't aware that malicious users can trivially %-encode the query string to bypass the RewriteCond.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.