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 '16 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. – Steve Sether May 25 '16 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 '16 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 '16 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 '16 at 18:26

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?

| improve this answer | |
  • 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? – Steve Sether May 25 '16 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 '16 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). – SilverlightFox May 26 '16 at 8:45
  • @SilverlightFox Fair point, I have toned it down to more of a suggestion. – Anders May 26 '16 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.

| improve this answer | |
  • 1
    Being about to set the value of the parameter does not equal unvalidated redirect. – Xander May 25 '16 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 '16 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.