Nginx location blocks syntax - nginx

I'm trying to return 400 status if someone includes this character '<' anywhere in the url request, for example the request might look like
https://example.com/adfg<script
I tried the following in Nginx location block, but obviously this is not how it works,
location /*<* {
return 400;
}
What's the right syntax that i need to write please.

"<" characters is not allowed in a url. Therefore you can't use it, maybe you want to use the url encoded version: "%3C".
Check: Characters allowed in a URL

Related

Redirect URI on NGINX

I have a page on my site (only accessible to logged in users), that looks like the following:
https://www.example.com/forum/new
However, sometimes when users click or refresh they get the page as follows:
https://www.example.com/forum%252fnew
Now %25 decodes to the % symbol, and %2f decodes to the "/", so it seems the URI is getting double-encoded.
I'm not sure how this encoding is happening, but I thought a workaround would be to have Nginx redirect back to the correct URL, with something like the following:
location ~ /forum%252Fnew {
return 301 https://www.example.com/forum/new;
}
I have tried escaping the % in the location with \, but neither seem to be working.
What am I missing?
The URI has been decoded and normalized before being processed by the location and rewrite directives, so the %25 looks like a single %.
The example in your question shows a regular expression location statement. The ~ operator is for case-dependent matching, whereas the ~* operator is for case-independent matching.
To make the example in your question work, you will need to change it to:
location ~* /forum%2Fnew
Or:
location ~ /forum%2fnew
See this document for details.

How to match requests containing greater-than symbol (<) in nginx?

I'm trying to harden a back end server, for which nginx is acting as a reverse proxy, against XSS and HTML injection attacks. I want to be able to simply respond with a 400 error to any request containing a '<' or a '>', either as part of the request or the query string (e.g., /LookupPrice?name=<"haarsy%0A>). I tried the following (for query_string) but the requests are still getting through:
if ($query_string ~* <){
return 400;
}
What do I need to do?
The request URI is percent encoded, so <> are often encoded as %3C and %3E (although they are not listed as reserved characters in RFC3986). Nginx will decode the characters to URI part when constructing the normalised URI variable $uri. But the query string remains percent encoded.
To match either < or > in the query string, whether percent encoded or not, use:
if ($query_string ~* (%3[CE]|[<>])) { return 400; }

Rewrite url without hash in nginx

I am trying to use Nginx rewrite static file path to strip the hash added for cache busting. The hash is always 10-symbol long. For example,
/min/3rd.party.min.1234567899.js has to become /min/3rd.party.min.js
I have tried this, but it doesn't work (fails at configtest) and also looks way to complicated.
location /min/ {
root /opt/app/public;
rewrite ^.*(?<=(.))[a-z0-9]{10}[.](?=(js|css))[js|css]$ $1$3;
}
I have no idea how you arrived at your regular expression pattern, but the following seems to work:
rewrite "^(.*)\.\w{10}\.(js|css)$" $1.$2 break;
Any pattern that contains a brace, must be placed within quotes. Use the break suffix to process the rewritten URI within the same location. See this document for details, and this useful resource on regular expressions.

Nginx - How to block all IPs except one

I'm a total Nginx newbie and I need some help. =]
I have a list of IPs contained within "$proxy_add_x_forwarded_for" which contains IPs separated by commas in this format: "IP, Next IP".
I'd like to return a 403 error code if MY IP is not within this comma separated list.
I thought the easiest way to do it would be to do a simple if statement to say: If $proxy_add_x_forwarded_for doesn't contain MY IP return 403.
Having tried this for ages I can't get anything to work, can anyone help me out? It sounds like this should be really easy.
Edit: Also I'm trying to set this up within the location block because there are other configurations using the Nginx and the IP restriction is only valid for this specific block.
Assuming that your IP address is 123.123.123.123, then the following statement will return 403 if your IP address is not present:
if ($proxy_add_x_forwarded_for !~ \b123\.123\.123\.123\b) { return 403; }
It uses the \b metacharacter to enforce word boundaries (which includes digits) so that the complete IP address is tested.
You can place the expression within a location block if you need to reduce its scope.
The if directive is documented here. See this caution on the use of the if directive. A useful resource for regular expressions is here.

how to match # character in a url in nginx through location directive

How do I match a # character in a url using location directive? I understand that we can use regex(PCRE), but their docs say that :
The location directive only tries to match from the first / after the hostname, to just before the first ? or #. (Within that range, it matches the unescaped url.)"
In short, How to match "example.com/#123456" using
location ~ [someregex] {
return 200 "matched";
}
or with any other alternative
Simple answer, you can't actually, because that part is never sent to the server to begin with, the only way to process this is to use Javascript, using location.hash
You can't because the ID hash isn't actually sent to the server, you might want to use GET variables like example.com?p=1234 if you intend to direct to a certain page or use location.hash if you wish to direct to a location on the page (which is its intended use)
Good luck!

Resources