This is the URL I need to match.
https://example.com/wp-login.php
https://example.com/wp-login.php?action=lostpassword
https://example.com/?s=
https://example.com/?s=xxxxxxx
This is the location matching rule I am using, it does not work, what is wrong please?
location ~* ^/(?:wp-login\.php|\?s\=) {
deny all;
}
CodePudding user response:
This is the common nginx novices error. Neither location
nor rewrite
directives works with the whole request URI. Both of them works with the normalized request URI which does not include the query string part at all (description of what URI normalization is can be found in the location
directive documentation). That means you can't check the query string using location
directive at all.
Usually what you are asking for can be achieved checking the $arg_<name>
nginx variable value, something like
if ($arg_s) {
return 403;
}
Unfortunately there is no way to distinct an empty query argument value from the absence of such an argument (well, at least without using third party modules like lua-nginx-module, where that difference can be actually checked against an empty string or a nil
value). Fortunately an original request URI is available to you via the $request_uri
internal variable, so you can do something like
if ($request_uri ~ \?(.*&)?s=) {
return 403;
}
location = /wp-login.php {
deny all;
}
or even use a single $request_uri
variable matching against a regex pattern like:
if ($request_uri ~ /wp-login\.php|\?(.*&)?s=) {
return 403;
}
(this should be placed at the server
configuration level)
CodePudding user response:
With your shown samples and attempts please try following regex.
(?:wp-login\.php(?:\?action=\S )?$|\?s=(?:\S )?)$
Here is the Online demo for regex.
Explanation: Adding detailed explanation for above.
(?: ##Starting 1st non-capturing group from here.
wp-login\.php ##matching wp-login.php here.
(?:\?action=\S )?$ ##In a non-capturing group matching ?action= followed by non-spaces and keeping this as an optional match.
| ##Putting OR condition either any of above OR following should match.
\?s= ##Matching literal ? followed by s=
(?:\S )? ##In a non-capturing group matching 1 or more non-spaces and keeping this match as an optional one.
)$ ##closing very first non-capturing group here.