PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, September 1, 2022

[FIXED] How to get nginx to do a redirect to url-encoded query parameter

 September 01, 2022     nginx, nginx-location, nginx-reverse-proxy     No comments   

Issue

I have a requirement to do a proxy call to url delivered via a query parameter as per example: My nginx proxy is deployed at: https://myproxy.net

if the redirect parameter is not url encoded I can do the call with this block:

  location /basepath {
        if ( $arg_redirect = '') { 
          return 400 "Missing redirect directive in request"; 
        }
        proxy_pass $arg_redirect;
        proxy_intercept_errors on;
        error_page 301 302 307 = @handle_redirects;
    }

the error intercepts and @handle_redirects then take care of othe 30X codes that might pop up at new destination.
This works for a request:
GET: https://myproxy.net/basepath?redirect=https://destination.com/somepath/uuid

What do I need to do to make it work for:
GET: https://myproxy.net/basepath?redirect=https%3A%2F%2Fdestination.com%2Fsomepath%2Fuuid

Additionally as part of spec it has to be pure nginx, not additional modules, lua etc. Thanks!


Solution

Actually, proxy_pass does normalisation by default, but it only affects $uri part. Thus you only need to decode the beginning of the passed string to get it working:

  location / {
    if ( $arg_redirect = '') {
      return 400 "Missing redirect directive in request";
    }
    if ( $arg_redirect ~ (.+)%3A%2F%2F(.+) ){ # fix :// between scheme and destination
      set $arg_redirect $1://$2;
    }
    if ( $arg_redirect ~ (.+?)%3A(.*) ){ # fix : between destination and port
      set $arg_redirect $1:$2;
    }
    if ( $arg_redirect ~ (.+?)%2F(.*) ){ # fix / after port, the rest will be decoded by proxy_pass
      set $arg_redirect $1/$2;
    }
    proxy_pass $arg_redirect;
  }

With the above I managed to access http://localhost/?redirect=http%3A%2F%2F127.0.0.1%3A81%2Fsfoo%20something%2Fs

The solution seems dirty and the only alternative using default modules is map (even less cleaner in my opinion). I'd rather split redirect argument into pieces: scheme (http or https), destination, port, and uri. With that you would be able to construct full address without rewriting:

proxy_pass $arg_scheme://$arg_dest:$arg_port/$arg_uri


Answered By - anemyte
Answer Checked By - Cary Denson (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing