Whitelist certain query string results in infinite redirect loop

jwxie nginx-forum at forum.nginx.org
Thu Aug 4 04:58:39 UTC 2016


Hi.

Our login page accepts a query parameter called client_id. Suppose we have
three applications and their respective client_ids are:

client_id=external-app
client_id=internal-app1
client_id=internal-app2

You may guess... behind the scene we do an oauth login that's why
"client_id" is in the url.

We do have separate nginx servers for handling external users so they won't
actually be able to see the internal app at all. What they can do is they
can try to brute force login an internal app.

Whitelist approach is usually better, espeically given we have more internal
applications than external applications. To test my theory, I tried

server {
    listen 0.0.0.0:80;
    server_name account.example.com;
    proxy_connect_timeout   60s;
    proxy_read_timeout      60s;
    proxy_send_timeout      60s;
    proxy_buffer_size       128k;
    proxy_buffers           4 256k;
    proxy_busy_buffers_size 256k;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    large_client_header_buffers 4 16k;


    set $backend "some-aws-elb.us-east-1.elb.amazonaws.com";
    resolver 10.0.0.2 valid=60s;

    location / {
                proxy_pass  http://$backend;
    }

    location /login {
        if ($args ~* "client_id=bad-client-id") {
          rewrite ^(.*)$ $1? redirect;
        }
        
        proxy_pass  http://$backend;
    }

}

Great. It works. If I replace bad-client-id with "bad-app1", when the user
opens "http://login.example.org/login?client_id=bad-app1", the user is
redirected back to "http://login.example.org/login"

So my next step is to do the negation (which effectively means "if $args
does not match this whitelisted client id, redirect), this way the attacker
can't quite guess which id is valid or not.

But I got a redirect loop.

if ($args !~* "client_id=good-client-id") {
          rewrite ^(.*)$ $1? redirect;
        }


Can someone suggest why I am getting a redirect loop? when I negate (!~*)?
This is running on port 80 for the sake of testing.

Thanks.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,268758,268758#msg-268758



More information about the nginx mailing list