Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop nginx from decoding URL

Tags:

nginx

I run an nginx server which serves static files. Some filenames contain strings like %3a.

/var/www/testfile%3a

If I try to request those files, I get a 404 Not Found error.

This seems to happen because nginx decodes the URL and replaces %3a with :, and then does not find a file named /var/www/testfile:. I infered this from the following debug output from nginx:

2018/06/21 10:03:21 [debug] 32523#0: *6 http process request line
2018/06/21 10:03:21 [debug] 32523#0: *6 http request line: "GET /testfile%3a HTTP/1.1"
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'2F:/'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:1 in:'74:t'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'65:e'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'73:s'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'74:t'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'66:f'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'69:i'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'6C:l'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'65:e'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'25:%'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:4 in:'33:3'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:5 in:'61:a'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'3A::'
2018/06/21 10:03:21 [debug] 32523#0: *6 http uri: "/testfile:"

So far, I came up with 2 possible solutions:

  • Rename all served files, so that %3a becomes : in the filename and educate every person who uploads files here about this.
  • Write a rewrite rule that escapes the % sign as %25. But I believe the rewrite-phase comes after the URL already has been decoded. Currently there are no unescaped : characters in the filenames, so I could rewrite : to %253a and that might work. Though there might be other characters in those filenames where this isn't possible, as they might be in the URL both in encoded and unencoded form.

I think there might be a simpler solution that I'm overlooking. Is there a way to tell nginx to treat every URL literally, e.g. without decoding escaped characters?

like image 833
david Avatar asked Oct 17 '25 07:10

david


1 Answers

If there is a percent sign in your URLs, just exchange the percent in your request with %25, like this:

https://domain/testfile%253a

This then becomes the file https://domain/testfile%3a.

The problem is not "Nginx decoding the URI" - you are trying to circumvent how normal URIs according to the RFC standard work, where the percent sign is always used to encode special characters. You might what to read the article about percent encoding and avoid all special characters which are used in URIs, because using those will all cause problems (characters like ?, &, #, and many more, and also :). For filenames it makes sense to avoid them completely, by for example replacing them with another character like _.

like image 153
iquito Avatar answered Oct 20 '25 15:10

iquito