Path Traversal is frighteningly simple

December 23, 2009

This StackOverflow question about path traversal prompted me to see how easy it is.

All it takes is a PHP file like this on your server:

<?php
// explore path traversal vulnerabilities
ini_set(‘display_errors’, ‘on’);
ini_set(‘error_reporting’, E_ALL);

$path = isset($_GET[‘path’]) ? $_GET[‘path’] : ‘’;

if (empty($path)) { echo “No path.”; die; }

echo $path . ‘<br/>’ . realpath($path) . ‘<hr/>’;

if (is_dir($path)) { echo ‘<pre>’ . print_r(scandir($path),true) . ‘</pre>’; } else { $file = file_get_contents($path); echo htmlspecialchars($file);
}

… and someone can gain total read access to your file system. Run that script with ?path=../../etc/passwd, for example, and the system’s user list is printed straight to the screen. (Because most Unix systems set –4 [all-read] permissions by default on system files.) (So DO NOT put that code on your server!

Of course, that exact code would never be used, but there are all kinds of other scenarios where user-submitted parameters or cookies are passed through to the file system. That’s one of the advantages of working in a framework (vs coding an app from scratch) - all these considerations have (presumably) been taken into account, and the API (if used correctly) should handle it. But it just reminds me how critical it is to escape all characters, never pass through form values directly, never load files based on unfiltered user input, etc etc… Apache’s access directives are useless once the script is running server-side.