Q: header redirect...not full url. security problem?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Q: header redirect...not full url. security problem?

Post by jmut »

Hi,
I think this topic is discussed but I just could not find anything :(
Can anyone point out how is

Code: Select all

header("Location: http://www.example.com/login.php");
different from

Code: Select all

header("Location: login.php"); //what is wrong with this approach.
Is it security problem or something.
Thanks a lot
User avatar
Obadiah
Forum Regular
Posts: 580
Joined: Mon Jul 31, 2006 9:13 am
Location: Ashland, KY
Contact:

Post by Obadiah »

i wouldn't say there is anything wrong with it...just one will go to a sit and the other to a local place on your machine or server....are you having problems with the latter?
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

not all browsers support relative urls. use the FULL url... http://www.yoursite.com/blabla.html

http://www.w3.org/Protocols/rfc2616/rfc ... l#sec14.30
W3C wrote:Location is that of the new resource which was created by the request. For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource. The field value consists of a single absolute URI.
Last edited by Luke on Wed Oct 18, 2006 11:50 am, edited 1 time in total.
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

From the PHP manual:
Note: HTTP/1.1 requires an absolute URI as argument to Location: including the scheme, hostname and absolute path, but some clients accept relative URIs
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Actually I think it has to be a really old browser for it to be an issue. I still use absolute URLs but I'm not sure how much it really matters these days. You can always do this:

Code: Select all

function redirect($relativeUrl) 
{
    header('Location: http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME']) . $relativeUrl);
    exit;
}
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post by jmut »

ole wrote:Actually I think it has to be a really old browser for it to be an issue. I still use absolute URLs but I'm not sure how much it really matters these days. You can always do this:

Code: Select all

function redirect($relativeUrl) 
{
    header('Location: http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME']) . $relativeUrl);
    exit;
}
also for the "http" part.......

Code: Select all

( isset($_SERVER['HTTPS'])) ? 'https' : 'http';

Ok thanks all. So I guess it does not matter that much. I though it might be security concern or something.

But really...I guess it is an old browser not responding issue.
Thanks again.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Great stuff. I'm going to put this in my library. Any other potential problems people can think of?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

$_SERVER['HTTPS'] can be defined but not in use (you're not running in secure) on some servers.

Check Burrito's geturl() function for an example.
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post by jmut »

feyd wrote:$_SERVER['HTTPS'] can be defined but not in use (you're not running in secure) on some servers.

Check Burrito's geturl() function for an example.
you mean servers like apache vs IIS for example....or even different configs with apache.

where can I see this geturl() function :roll:
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

I don't see Buritto's, but here's a geturl function in the Code Snippets forum ( :o )

viewtopic.php?t=24358&highlight=geturl
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

d3ad1ysp0rk wrote:I don't see Buritto's, but here's a geturl function in the Code Snippets forum ( :o )

viewtopic.php?t=24358&highlight=geturl
viewtopic.php?t=37950 :)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Code: Select all

/**
 * Preform a HTTP(S) redirect. Supports relative or absolute path.
 *
 * @param string $input
 */
function OSIS_Redirect($input)
{
    static $protocol = null;
    if ($protocol === null) {
        if (empty($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') {
            $protocol = 'http';
        } else {
            $protocol = 'https';
        }
    }
    static $port = null;
    if ($port === null) {
        $ports = array('https' => 443, 'http' => 80);
        if ($_SERVER['SERVER_PORT'] != $ports[$protocol]) {
            $port = ':' . $_SERVER['SERVER_PORT'];
        } else {
            $port = '';
        }
    }

    if ($input[0] == '/') { // absolute
        $path = array('');
    } else { // relative
        $path = explode('/', dirname($_SERVER['SCRIPT_NAME']));
    }
    $input = explode('/', $input);

    foreach ($input as $part) { // resolve to absolute
        if ($part == '.' || $part == '') {
            continue;
        }
        if ($part == '..') {
            array_pop($path);
            continue;
        }
        $path[] = $part;
    }

    $path = implode('/', $path);
    return "Location: $protocol://{$_SERVER['HTTP_HOST']}$port$path";
}
These pass:

Code: Select all

public function testRedirect()
    {
        $originalServer = $_SERVER;
        $_SERVER['HTTP_HOST'] = 'zim.com';
        $_SERVER['SCRIPT_NAME'] = '/foo/bar/gir.php';
        unset($_SERVER['HTTPS']);

        $this->assertEqual(OSIS_Redirect('dib.php'), 'Location: http://zim.com/foo/bar/dib.php');
        $this->assertEqual(OSIS_Redirect('..//gaz.php'), 'Location: http://zim.com/foo/gaz.php');
        $this->assertEqual(OSIS_Redirect('/abs.php'), 'Location: http://zim.com/abs.php');
        $this->assertEqual(OSIS_Redirect('../.././pig.php'), 'Location: http://zim.com/pig.php');
        $this->assertEqual(OSIS_Redirect('dad/../../../gaz.php'), 'Location: http://zim.com/gaz.php');

        $_SERVER = $originalServer;
    }
By no means an exhaustive test. I still haven't fully got into the habbit of writing tests first so I butchered it with all that portability stuff without any tests. Hmmm, I'll do some more later.

Oh yeah and I'm posting this here for comments and criticism. If someone wants to finish testing it for me that would be nice too :)
Post Reply