openresty / lua-nginx-module

Embed the Power of Lua into NGINX HTTP servers
https://openresty.org/
11.22k stars 2.02k forks source link

http headers vs unescape_uri bug #941

Open antony66 opened 7 years ago

antony66 commented 7 years ago

I am not sure if this is resty bug or nginx bug, but here's how to reproduce it:

  1. Set up nginx as pop3 proxy:
mail {
    auth_http 127.0.0.1:8080/auth;
    pop3_auth         plain;
    ....
  1. Set up 127.0.0.1:8080/auth as a lua generated content:
server {
    listen 127.0.0.1:8080;
    location /auth {
        content_by_lua_block {
            local pass = ngx.unescape_uri(ngx.var.http_auth_pass)
            ngx.log(ngx.ALERT, "Before: ", ngx.var.http_auth_pass, ", after: ", pass)
        }
    }
}
  1. Telnet to your nginx pop3 port and try to provide password like "ca ffe+19" (with space and plus characters)

Here's what you get in error.log:

Before: ca%20ffe+19, after: ca ffe 19

So instead of "ca ffe+19" one would get back "ca ffe 19" where plus char is replaced with space.

qleein commented 7 years ago

ngx.unescape_uri() would decode '+' to whitespace. Here is a discription on wikipedia. https://en.wikipedia.org/wiki/Percent-encoding#The_application.2Fx-www-form-urlencoded_type

antony66 commented 7 years ago

It is expected that ngx.unescape_uri() would decode back a string encoded by nginx. It doesn't happen correctly.

detailyang commented 7 years ago

@antony66 It meet our expecation. As @qlee001 says, the real percent encoding uses %20 while form data in URLs is in a modified form that uses +. And the codebase had point out this.

antony66 commented 7 years ago

Plus should be converted to %0B, and then back to plus. Now look at what lua shows as incoming http_auth_pass