19

Are there any escape routines that need to be done to user data for it to be used inside PHP's header() function?
Eg for MySQL I run mysql_real_escape_string() over user data before sending it to the DB and for output in HTML I run htmlspecialchars()... both wrapped in my own custom function to do some other processing first.

But for PHP's header() function, what needs to be done? Are there any dangerous characters that I should escape?

I'm trying to do something like this... appending the query string to a header() redirect to a different page

if ( strlen($_SERVER['QUERY_STRING']) > 0) {
$query_string = '?'.$_SERVER['QUERY_STRING'];
}
header('Location: http://domain.com/activate.php'.$query_string);
exit();

Anyone got any info on what needs to be escaped for the header() function? Colon and semi-colon characters always seem pretty critical to header() statements. Should I escape those?

batfastad
  • 1,943
  • 3
  • 27
  • 37

3 Answers3

18

No, there is nothing that you need to do to protect yourself as long as you're using PHP >= 4.4.2 (if on PHP4) and >= 5.1.2 (if PHP5).

See the docs for header(). Specifically:

This function now prevents more than one header to be sent at once as a protection against header injection attacks.

So there's no significant need to escape anything for a Location Header. If you're on earlier versions, you'd need to escape all \r and \n characters (to prevent header injection).

Also, don't urlencode the query string. It will break the semantic meaning of the data being sent. Just append it in full.

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
  • Great info! Yeah I definitely should have looked at that first and also posted my php version in the Q. Fortunately this particular server's running php 5.2.11 so hopefully covered. – batfastad Apr 15 '11 at 22:44
  • Escapting \r and \n: `$text = str_replace("\r\n",'', $text);` – Jack May 11 '16 at 21:19
  • I don't know if anything is needed to make the content passed into header() safe, but this answer isn't very convincing. First off, the logic isn't very sound. Even if the documentation said it prevents more than one header sent as a protection against header injection attacks, that is very different from saying it provides complete protection from every possible type of injection, escaping everything that would need to be escaped. It's only saying it won't send multiple headers. Secondly, the documentation is no longer worded that way, probably to avoid this very confusion. – still_dreaming_1 Mar 18 '23 at 12:31
  • How do you know `rawurlencode()` isn't needed for parts of a URL that would be invalid as a URL? Are you saying it will translate that for you? I don't know if it needs to be called or not, but this is not convincing. – still_dreaming_1 Mar 18 '23 at 12:34
1

There could be some exploits used there, like multiple headers sent, despite the fact that if you are running PHP5.1 this is prevented by PHP it selfs are reported here:

4.4.2 and 5.1.2: This function now prevents more than one header to be sent at once as a protection against header injection attacks.

A part from that, if you are expecting a query string to be attached to that file and you are not using SEO urls you should validate the query string with urlencode() which will check whatever the string is a query string or not and will replace strange chars or not allowed chars with appropriate % and +.

References:

Shoe
  • 74,840
  • 36
  • 166
  • 272
1

You can also use http_build_query to convert an associated array into the query string.

<?php
    $data = array('foo'=>'bar',
          'baz'=>'boom',
          'cow'=>'milk',
          'php'=>'hypertext processor');

    echo http_build_query($data) . "\n";
?>

The above example will output:

foo=bar&baz=boom&cow=milk&php=hypertext+processor
Josh Brown
  • 935
  • 1
  • 11
  • 21