Whitelist certain query string results in infinite redirect loop

Francis Daly francis at daoine.org
Thu Aug 4 07:24:06 UTC 2016


On Thu, Aug 04, 2016 at 12:58:39AM -0400, jwxie wrote:

Hi there,

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

That says:

if I ask for /login/something?key=value&client_id=bad-client-id, I get
a http redirect to /login/something. Then if I ask for /login/something,
I do not match the "if" so I go to proxy_pass.

> 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.

That says:

if I ask for /login/something?key=value&client_id=bad-client-id, I get a
http redirect to /login/something. Then if I ask for /login/something, I
match the "if" again so I get a http redirect to /login/something.

That's the loop.

I would suggest using map (http://nginx.org/r/map) to set a variable
based on $arg_client_id; and then test for that variable in the "if". The
exact logic will depend on what exactly you want to do, what input you
expect, etc.

Good luck with it,

	f
-- 
Francis Daly        francis at daoine.org



More information about the nginx mailing list