10

This isn't working:

<?php
header('Location: www.mysite.com/index.php?foo=bar&var=abc');
?>

I end up with www.mysite.com/index.php?foo=bar I think HTML might be trying to interpret the &var as a character. The initial variable is passed (after ?) but all subsequent are not (after &).

joedborg
  • 17,651
  • 32
  • 84
  • 118
  • 3
    According to the HTTP specifications, Location headers must include a complete URL. This is a bit of a wild guess, but try adding http:// at the front. Aside from that, maybe post more code? – Corbin Sep 09 '11 at 10:41
  • Can you post your actual code then? And have you tried echoing out the string being passed to header()? It's possible that the string is not what you think it is. The example above looks valid and would retain both foo and var. – Corbin Sep 09 '11 at 10:47
  • write them like `&`. i.e write `&` instead of `&` – Achshar Sep 09 '11 at 10:49
  • err scratch that.. it is only for HTML sorry :( – Achshar Sep 09 '11 at 10:51
  • Have you tried replacing `&` with `&`? Just a wild guess. Edit: Seems Achshar got there before me! – pb149 Sep 09 '11 at 10:52
  • I've just used a tag instead, it's done the trick! – joedborg Sep 09 '11 at 10:52
  • 1
    header('Location: '.$_SERVER['SERVER_NAME'].'/index.php?'.$_SERVER['QUERY_STRING']); – confucius Sep 09 '11 at 10:53
  • 1
    @Nammari http://stackoverflow.com/questions/4581837/is-serverquery-string-safe-from-xss and jdborg you should probably add that as an answer then or close the question :O – Achshar Sep 09 '11 at 10:54
  • Ah, worked a treat Nammari! Put it as the answer please. – joedborg Sep 09 '11 at 10:55
  • with proper parsing/escaping please.. ^^ – Achshar Sep 09 '11 at 10:57
  • @Achshar I'm using it for an intranet so all good – joedborg Sep 09 '11 at 11:01
  • @jdborg hmm but remember you are not the only one who will be seeing the answer. People look up for answers here and someone can use the unsafe code (which is secure for you but you are an exception) – Achshar Sep 09 '11 at 11:03

3 Answers3

5
if( isset($_SERVER['HTTPS'] ) ) {
  header('Location: https://'.$_SERVER['SERVER_NAME'].'/index.php?'.$_SERVER['QUERY_STRING']);
}
else{
  header('Location: http://'.$_SERVER['SERVER_NAME'].'/index.php?'.$_SERVER['QUERY_STRING']);
} 

use htmlspecialchars to prevent html injection

malhal
  • 26,330
  • 7
  • 115
  • 133
confucius
  • 13,127
  • 10
  • 47
  • 66
  • 1
    i am saying this again, that kind of code is unsafe. http://stackoverflow.com/questions/4581837/is-serverquery-string-safe-from-xss – Achshar Sep 09 '11 at 11:02
  • 3
    htmlspecialchars has no meaning to a header... HTML escaping only makes sense in the realm of HTML. Additionally, as I mentioned earlier, it is incorrect to not have the http:// at the front (or https://). Omission is incorrect by the HTTP standards. – Corbin Sep 09 '11 at 11:13
  • 4
    I know it seems like I'm being picky, but it seems that 90% of every header I see is wrong these days and it's really begun to annoy me. The Location header will now be correct, however your htmlspecialchars advice is still completely incorrect. A URL has no concept of HTML. Only HTML has a concept of HTML (as silly as that sounds). & is supposed to be & in a URL, not &. HTML escaping a URL in a HTML context is correct. Doing it in a header context is wrong. – Corbin Sep 09 '11 at 11:21
  • 1
    @Achshar: the question you link is about injecting raw user input in the site's HTML. I can't see how it applies to HTTP headers. – Álvaro González Sep 09 '11 at 12:00
  • how about something on the lines of `url'); ?> – Achshar Sep 09 '11 at 12:22
  • Nothing ensures that the query string is ever output though. URLs should be html escaped when being printed in an html document, not when being used as URLs. As I said before, HTML has no meaning in a URL; HTML only has meaning in HTML. Would you escape HTML for a mp3 document? No. HTML and HTTP are not explicitly linked. – Corbin Sep 09 '11 at 22:47
0

Redirecting index.php to hompage. same can be used for any other page redirection.

$url = str_replace('/index.php', '/', $_SERVER['REQUEST_URI']);
header('Location: '. $url, true,302);
exit();
Ali Azhar
  • 1,703
  • 19
  • 14
0

I was testing that case with this:

    <?php
    if (isset($_GET['foo']) ) { 
        echo '<pre>';
        print_r($_GET);
        echo '</pre>';
        exit(); 
    }
    $fp='http://server/header.php?foo=bar&var=abc';
    header("Location: ".$fp);
    exit();
    ?>
    

I call the address: http://server/header.php and the redirect works fine to 'http://server/header.php?foo=bar&var=abc' and the _GET is complete:

Array
(
    [foo] => bar
    [var] => abc
)

Notice:

  1. location with first letter as capital letter.
  2. the colon and space after "Location"
  3. the full link
  4. the exit() call.
On the other hand, make sure that nothing is outputed to the browser BEFORE THE REDIRECT EXECUTES.