Question: I have a base path /whatever/foo/

and
`$_GET['path']` should be relative to it.

However how do I accomplish this (reading the directory), without allowing directory traversal?

eg.

```
/\.\.|\.\./

```

Will not filter properly.

Answer: 
ircmaxell's answer wasn't fully correct. I've seen that solution in several snippets but it has a bug which is related to the output of `realpath()`. The `realpath()` function removes the trailing directory separator, so imagine two contiguous directories such as:

```none
/foo/bar/baz/

/foo/bar/baz_baz/

```

As `realpath()` would remove the last directory separator, your method would return "good path" if `$_GET['path']` was equal to "../baz\_baz" as it would be something like

```
strpos("/foo/bar/baz_baz", "/foo/bar/baz")

```

Maybe:

```
$basepath = '/foo/bar/baz/';
$realBase = realpath($basepath);

$userpath = $basepath . $_GET['path'];
$realUserPath = realpath($userpath);

if ($realUserPath === false || strcmp($realUserPath, $realBase) !== 0 || strpos($realUserPath, $realBase . DIRECTORY_SEPARATOR) !== 0) {
    //Directory Traversal!
} else {
    //Good path!
}

```
I have written a function to check for traversal:

```
function isTraversal($basePath, $fileName)
{
    if (strpos(urldecode($fileName), '..') !== false)
        return true;
    $realBase = realpath($basePath);
    $userPath = $basePath.$fileName;
    $realUserPath = realpath($userPath);
    while ($realUserPath === false)
    {
        $userPath = dirname($userPath);
        $realUserPath = realpath($userPath);
    }
    return strpos($realUserPath, $realBase) !== 0;
}

```

This line alone `if (strpos(urldecode($fileName), '..') !== false)` should be enough to prevent traversal, however, there are many different ways hackers can traverse directories so its better to make sure the user starts with the real base path.

Just checking the user starts with the real base path is not enough because a hacker could traverse to the current directory and discover the directory structure.

The `while` allows the code to work when $fileName does not exist.