I have reviewed a web application built on PHP. It redirects to different pages this way:

$param = $_POST['param'];
header('Location: ../page.php?param='.$param);

Is it vulnerable to unvalidated redirects? In other words, can I redirect to another web site, manipulating the parameter param?

  • Have you tried it? Does it work?
    – Xander
    May 25, 2016 at 17:58
  • it depends on where $param comes from. Normally we're concerned about user A redirecting user B. But we're not concerned about user A redirecting user A. May 25, 2016 at 17:58
  • @Xander I didn't try it, firstly because my job is code review, second I don't have any idea how to exploit it.
    – hmrojas.p
    May 25, 2016 at 18:06
  • @SteveSether $param comes from an form input, this parameter must be an integer, but there isn't a validation for this parameter..
    – hmrojas.p
    May 25, 2016 at 18:10
  • 1
    @SteveSether Yeah you right, maybe I don't explain it very well, I do code review and penetration testing, but as I told you, I don't have any idea how to test it, for this reason I asked this question, I wanted to know if someone would know if this kind of redirection is vulnerable to "Unvalidated Redirects" and how to test it.
    – hmrojas.p
    May 25, 2016 at 18:26

2 Answers 2


I don't think there is a risk for an open redirect vulnerability, since anything after the ? will be interpreted as query parameters and not a part of the path. But you should change your code anyway, since you do not make sure that the param is actually URL-encoded. Do this with urlencode():

header('Location: ../page.php?param='.urlencode($param));

However, if you use a version of PHP older than 5.1.2 you are vulnerable to header injection (see documentation). By sending a param that includes a newline an attacker could set multiple headers (or just set the location header again, overwriting the old value). Using urlencode() fixes that since \n would be encoded as %0A.

The whole construct could be unnecessary though - perhaps you can just check both $_POST and $_GET for param in page.php?

  • My guess is you're right, but the more cautious answer is "who knows". You can't do any real analysis from a code snippet. How do you know what happens after the snippet, and before the snippet? May 25, 2016 at 18:32
  • 1
    @SteveSether I think the level of agnostisism you call for is unwarranted. I can say that the above code will not set the location header to another domain, no matter what code is above or below the snippet. If you disagree with my answer, you are offcourse welcome to write your own.
    – Anders
    May 25, 2016 at 18:42
  • I was with you until the last paragraph. It could be that page.php is only redirected to under certain circumstances (e.g. other parameters not in the posted code snippet). May 26, 2016 at 8:45
  • @SilverlightFox Fair point, I have toned it down to more of a suggestion.
    – Anders
    May 26, 2016 at 8:48

Short answer: Yes.

Long answer: Yes, but it depends. We don't have a page.php code so we can only guess what that page does in the background. Still, any parameter sent either through POST or GET (or any other request for that matter) is allowed to be edited by end-used. So manipulation is of course possible. Read more about POST (HTTP) and HTTP if you want to know more.

Why: From the snippet you've posted, we can see that no escape for the POST parameter is set. That way, attacker can set the POST parameter to any value.

To exploit it, you can use curl or postman and set any value on the $_POST['param'] parameter.

  • 1
    Being about to set the value of the parameter does not equal unvalidated redirect.
    – Xander
    May 25, 2016 at 18:21
  • I think the question is about open redirects, and not vulnerabilities in general. So whats in page.php is irrelevant - if the user was redirected to it the redirect was not used to redirect the user somewhere else.
    – Anders
    May 25, 2016 at 18:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .