note 40603 deleted from security.filesystem by nlopess
| From: | nlopess@php.net | Date: | Tue, 09 Mar 2004 15:01:32 +0000 |
| Subject: | note 40603 deleted from security.filesystem by nlopess | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-66503@lists.php.net to get a copy of this message | ||
Note Submitter: crysaz@zerodistance.org
----
My solution to /home/user/../../dev/ problem. Every directory change is tested and checked against
"root" directory. You can't jump two steps att once.
<?php
$root = "/path/to/rootdir"; // script doesn't go under this
if (isset($_SESSION['cwd']) && $_SESSION['cwd'] !== $root) {
$cwd = $_SESSION['cwd'];
} else {
$cwd = $root;
if (isset($_SESSION['cwd'])) {
unset($_SESSION['cwd']);
}
}
if (isset($_GET['dir']) && !empty($_GET['dir'])) {
$req_dir = $cwd . "/" . $_GET['dir'];
if (realpath($req_dir . "/..") == $cwd) {
// $cwd is $req_dir's root directory
$_SESSION['cwd'] = $req_dir;
} elseif (realpath($req_dir) == realpath($cwd . "/..") &&
isset($_SESSION['cwd'])) {
// $req_dir is root for $cwd and $_SESSION['cwd'] is set (so we aren't in $root)
$_SESSION['cwd'] = realpath($req_dir);
} else {
$req_dir = $cwd;
}
} else {
$req_dir = $cwd;
if (isset($_SESSION['cwd'])) {
// we don't wanna go under $root so let's unset $_SESSION['cwd']
unset($_SESSION['cwd']);
}
}
?>
Now you have secure $cwd witch contence you can loop throught readdir() with assistance of is_dir()
and is_file().
Took a while to figure this out. Works fine for me. Hope this helps.