Opened 4 years ago

Last modified 3 years ago

#508 new defect

nginx rewrite URL decoding first encoded character in URI

Reported by: www.google.com/accounts/o8/id?id=AItOawk5aGHLHDQT1FbwrATf1n1GjsLKwcfgUCU Owned by:
Priority: major Milestone:
Component: nginx-core Version: 1.5.x
Keywords: Cc:
Sensitive: no
uname -a: Linux Nginx-Test-Zusw1b-S01 2.6.38-13-virtual #57-Ubuntu SMP Mon Mar 5 21:49:53 UTC 2012 i686 i686 i386 GNU/Linux
nginx -V: nginx version: nginx/1.5.10 built by gcc 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) TLS SNI support enabled configure arguments: --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --prefix=/opt/nginx-1.5.10 --http-client-body-temp-path=/var/opt/nginx/client_body_temp --http-fastcgi-temp-path=/var/opt/nginx/fastcgi_temp --http-proxy-temp-path=/var/opt/nginx/proxy_temp --http-scgi-temp-path=/var/opt/nginx/scgi_temp --http-uwsgi-temp-path=/var/opt/nginx/uwsgi_temp

Description

I have rules like the following:

location /trk/ {

if ($args ~ "url=(.*)" ) {

set $url $1;
rewrite click.gif$ $url? redirect;
rewrite redirect.gif$ $url? redirect;

}

}

problem is if I have a request like:

http://localhost/trk/click.gif?some_foo&url=http://www.foo.com/%3Fmore_foo%3F

it gets rewritten to

http://www.foo.com/?more_foo%3F

and I need the first %3F to not get decoded to ?

It appears to decode the FIRST and only the first encoded character it finds...

I've tried this with several version of nginx (1.1.13, 1.3.2 and 1.5.10) - output of nginx -V is below for 1.5.10.

here's the issue:

ubuntu@Nginx-Test-Zusw1b-S01:~$ GET -Sd "http://localhost/trk/click.gif?some_foo&url=http://www.foo.com/%3Fmore_foo%3F"
GET http://localhost/trk/click.gif?some_foo&url=http://www.foo.com/%3Fmore_foo%3F --> 302 Moved Temporarily
GET http://www.foo.com/?more_foo%3F --> 200 OK

Maybe this is a "feature" but I'm unable to find it documented anywhere nor do have I found a way to "turn it off"

Change History (1)

comment:1 Changed 3 years ago by www.google.com/accounts/o8/id?id=AItOawk5aGHLHDQT1FbwrATf1n1GjsLKwcfgUCU

I solved this with some code like:

location /trk/click.gif {

if ($args ~ "url=(.*)" ) {

return 302 $1;

}
empty_gif;
expires 0;
add_header Cache-Control "no-cache, no-store, must-revalidate";

}

so never mind :)

Note: See TracTickets for help on using tickets.