1

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.

4
  • 404 isn't a redirect, so R=404 doesn't make sense, you can change that flag, with the F (403 forbidden) or G (410 gone) Commented Oct 14, 2020 at 8:40
  • also, maybe you want to give mod_security a look. Commented Oct 14, 2020 at 8:44
  • And your expression in the condition needs to be reversed. You want to redirect if the testword is present in the query string, so the negation ("!") does not make any sense in the condition. Commented Oct 14, 2020 at 11:58
  • @on8tom R=404 makes perfect sense. The R flag is multi-purpose. It isn't only for external redirects. Behaviour is different when specifying a non-3xx HTTP status. (Just as you can use non-3xx status codes with the mod_alias Redirect and RedirectMatch directives.) Commented Oct 14, 2020 at 20:56

1 Answer 1

2
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]
Sign up to request clarification or add additional context in comments.

1 Comment

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.