Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#727 closed defect (invalid)

Nginx pass_proxy subdirectory without url decoding

Reported by: www.google.com/accounts/o8/id?id=AItOawkVOPK43vnk8eQ_qTnBT6VhSgo3GPf4VzA Owned by:
Priority: major Milestone:
Component: nginx-core Version: 1.2.x
Keywords: proxy_pass Cc:
uname -a: Linux ip-10-73-181-14 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.2.1 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-auth-pam --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-echo --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-upstream-fair --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-dav-ext-module

Description

Hello guys,

First of all thank you for this amazing server!

Here's an issue I'm trying to solve: I need to write an nginx location directive to proxy requests for subdirectory to another server preserving urlencoding and removing subdirectory prefix.

Here's an artificial example — request like this:

http://1.2.3.4/api/save/http%3A%2F%2Fexample.com

should pass as

http://abcd.com/save/http%3A%2F%2Fexample.com

I tried several different ways. Here're couple of them:

        location /api/ {
            rewrite ^/api(/.*) $1 break;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header   Host             $host;
            proxy_pass http://abcd.com;
        }

But it decodes the string, so http://abcd.com gets /save/http://example.com

        location /api/ {
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header   Host             $host;
            proxy_pass http://abcd.com;
        }

But it keeps subdirectory, so http://abcd.com gets /api/save/http%3A%2F%2Fexample.com.

Here's the question on SO

Is it correct to keep special characters such as ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," decoded after processing? Is there some workaround for this issue? I would prefer to use subdirectory instead of subdomain since this way you don't have to worry about CORS etc

Thanks a lot!

Change History (2)

comment:1 Changed 5 years ago by mdounin

  • Resolution set to invalid
  • Status changed from new to closed

Characters which are not allowed to be passed unescaped are escaped after URI transformation. The ":" and "/" characters are allowed within URI (though may have special meaning in some cases).

If you want nginx to do something custom, you can do so using proxy_pass with variables (and the $request_uri variable, which contains original unescaped request URI as sent by a client). In this case it will be your responsibility to do correct URI transformations. Note though that this can easily cause security issues and should be done with care.

comment:2 Changed 5 years ago by www.google.com/accounts/o8/id?id=AItOawkVOPK43vnk8eQ_qTnBT6VhSgo3GPf4VzA

Hello Maxim,

I guess RFC 2616 https://www.ietf.org/rfc/rfc2616.txt section 3.2.3 and RFC 2396 https://www.ietf.org/rfc/rfc2396.txt section 2.2 says that special characters like / are not the same as %2F, so they probably shouldn't be decoded at all by proxy, is it my misunderstanding? What kind of "Characters which are not allowed to be passed unescaped" do you mean in this case?

Thank you

Note: See TracTickets for help on using tickets.