htaccess send 404 if query string contains keyword

1.3k Views Asked by At

I'm seeing a lot of traffic which I suspect is probing for a flaw or exploit with the request format of

https://example.com/?testword

I figured while I look into this more I could save resources and disrupt or discourage these requests with a 404 or 500 response

I have tried

RewriteEngine On
RewriteCond %{QUERY_STRING} !(^|&)testword($|&) [NC]
RewriteRule https://example.com/ [L,R=404]

And some other variations on the Query string match but none seem to return 404 when testing. Other questions I have found look for query string values/pairs and rewrite them but no examples seem to exits for just a single value.

1

There are 1 best solutions below

1
On BEST ANSWER
RewriteCond %{QUERY_STRING} !(^|&)testword($|&) [NC]
RewriteRule https://example.com/ [L,R=404]

There are a few issues here:

  • The CondPattern in your condition is negated (! prefix), so it's only successfull when the testword is not present in the query string.

  • The RewriteRule directive is missing the pattern (first) argument (or substitution (second) argument depending on how you look at it). The RewriteRule directive matches against the URL-path only.

  • When you specify a non-3xx status code for the R flag, the substitution is ignored. You should specify a single hyphen (-) to indicate no substitution.

To test that the whole-word "testword" exists anywhere in the query string, you can use the regex \btestword\b - where \b are word boundaries. Or maybe you simply want the regex testword - to match "testword" literally anywhere, including when it appears as part of another word? In comparison, the regex (^|&)testword($|&) would miss instances where "testword" appears as a URL parameter name.

Try the following instead:

RewriteCond %{QUERY_STRING} \btestword\b [NC]
RewriteRule ^$ - [R=404]

This matches the homepage only (ie. empty URL-path). The L flag is not required when specifying a non-3xx return status, it is implied.

The - (second argument) indicates no substitution. As mentioned above, when specifying a non-3xx HTTP status, the substitution string is ignored anyway.

To test any URL-path then simply remove the $ (end-of-string anchor) on the RewriteRule pattern. For example:

RewriteCond %{QUERY_STRING} \btestword\b [NC]
RewriteRule ^ - [R=404]

If your homepage doesn't accept any query string parameters then you could simply reject the request (ie. 404 Not Found) when a query string is present. For example:

RewriteCond %{QUERY_STRING} .
RewriteRule ^$ - [R=404]