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!
}

```
When looking into the creation of new files or folders, I've figured I can use a two stage approach:

First check for traversal attempts using a custom implementation of a `realpath()` like function, which however works for arbitrary paths, not just existing files. There's a good starting point [here](https://www.php.net/manual/en/function.realpath.php#84012). Extend it with `urldecode()` and whatever else you think may worth checking.

Now using this crude method you can filter out some traversal attempts, but it may be possible that you miss some hackish combination of special characters, symlinks, escaping sequences etc. But since you know for sure the target file does not exist (check using `file_exists`) noone can overwrite anything. The worst case scenario would be that someone can get your code creating a file or folder somewhere, which may be an acceptable risk in most cases, provided your code does not allow them to write into that file/folder straight away.

Finally so the path now points to an existing location, therefore you can now do the proper check using the methods suggested above utilising `realpath()`. If at this point it turns out a traversal has happened, you are still safe more or less, as long as you make sure to prevent any attempts writing into the target path. Also right now you can delete the target file/dir and say it was a traversal attempt.

I'm not saying it cannot be hacked, since after all still it may allow illegitimate changes to be done to the FS, but still better than only doing custom checks, that cannot utilise `realpath()`, and the window for abuse left open by making a temporary and empty file or folder somewhere is lower, than allowing them to make it permanent and even write into it, as it would happen with only a custom check that may miss some edge cases.

Also correct me if I'm wrong pls!