I'm trying to use Nginx Location to block requests similar to this, which are causing load issues with WordPress (and the multilingual WPML plugin):
GET /foo/bar/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/ HTTP/1.1
However simplifying it to the following doesn't match:
location ~* \?s= {
return 404;
}
even though I've:
?
, but not the =
(have tried that too)^
and $
to avoid slashes creating any confusion~*
for case-insensitive(I can confirm that location foobar
will correctly match "foobar" anywhere in the URL.)
The PCRE regex is correct. A test against Perl (the source of the Perl Compatible Regular Expressions) which are used by nginx according to the sources:
perl -e 'print "yes\n" if "/foo/bar/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/?s=/" =~ m|\?s=/|'
yes
The reason why it does not match is, that the location { } match only matches against the URL, not the URI (which includes the params).
So anything that follows after the ? will be ignored in the location match block.
The way to fix this is by useing the complete uri to match, not just the URL:
if ( $request_uri ~ s=/ ) {
return 404;
}
Or if you want to include /foo/bar:
location /foo/bar {
if ( $request_uri ~ s=/ ) {
return 404;
}
}