Encoding URL before passing it on to reverse proxied application

Maxim Dounin mdounin at mdounin.ru
Thu Oct 18 14:36:05 UTC 2018


On Thu, Oct 18, 2018 at 04:18:50PM +0200, Garbage at gmx.de wrote:

> We are in the process of replacing a rather old web application. The old application used links that look like this:
> https://nameofapp/do?param1=A&id={ABC-DEF-GHI}&param2=B
> I know that as far as RFC is concerned { and } are not valid characters but unfortunately the application was built that way and we have 100s of 1000s of links that were stored by users and we can't replace them (the links ;-))
> The new application is based on Spring Boot and has to be prefixed by a nginx webserver. Nginx takes the URL and proxies it to the Spring Boot application like this:
> location / {
>   proxy_pass http://localhost:8080;
> }
> While doing this nginx keeps the { and } in place, then Spring Boots built in security firewall complains about those characters and sends a http status 400. I do not want to switch off this feature (although it would be possible). Instead I search for a way to achieve one of these:
> - have nginx "process" the URL and encode the { and } before passing them on. For example this could look like "/do?param1=A&id=%7BABC-DEF-GHI%7D&param2=B"
> - have nginx "hide" the complete URL, for example this could like like "/processhiddenvalue?value=ZG8/cGFyYW0xPUEmaWQ9e0FCQy1ERUYtR0hJfSZwYXJhbTI9Qg==" (which is just the base64 encoded URL)
> Is one of these approaches possible ?

You can easily do something like this:

   rewrite ^ /foo? break;
   proxy_pass http://localhost:8080;
   proxy_set_header X-Original-URI $request_uri;

This will replace the URI as seen by the upstream server to 
"/foo" without any request arguments, and the original request URI 
will be sent in the X-Original-URI header.

Replacing "{" and "}" characters should be also possible, though 
will require some more sophisticated scripting.  For example, the 
following code:

if ($args ~ "(.*){(.*)") { set $args $1%7B$2; }
if ($args ~ "(.*){(.*)") { set $args $1%7B$2; }
if ($args ~ "(.*)}(.*)") { set $args $1%7D$2; }
if ($args ~ "(.*)}(.*)") { set $args $1%7D$2; }

will replace up to two occurences of "{" and "}" in the request 

Maxim Dounin

More information about the nginx mailing list