Reputation: 4941
I am trying to get regex to tell me if a path contains ./
or ../
. This is to check a user doesn't look beyond their area. If the input contains a period before a forward slash it wont be accepted.
E.g.
/user/selected/path/ - Ok
./user/selected/path/ - Failed
../user/selected/path/ - Failed
The forward slash will be replaced with DIRECTORY_SEPERATOR so works for unix and windows paths.
Upvotes: 0
Views: 134
Reputation: 26658
$myString = "some/path";
if (preg_match('/(\.\.\/|\.\/)/', $myString)) {
echo "found ../ or ./ in path";
}
Upvotes: 0
Reputation: 449623
Checking for the existence of ".." is an imperfect solution to the problem.
If you want to prevent the user from breaking out of a base directory, check whether the realpath()
result of the path (which will take into account relative paths) is still underneath the root path.
Example:
$root = "/my/user/basepath";
$requested_path = $_GET["input"]; // or whatever
$real_path = realpath($root."/".$requested_path);
if (strpos($real_path, $root) !== 0)
die ("Illegal path");
Upvotes: 6
Reputation: 1110
I'd
a) recommend strpos for something this simple, not regex functions.
$usrPath = '../some/path/';
if (strpos($usrPath, '.' . DIRECTORY_SEPARATOR) !== false){
die('oh no you don\'t');
}
b) Recommend making sure your server setup and filesystem permissions are set to prevent any chance of a user getting 'beyond their area', rather then programmatic methods.
Upvotes: 0
Reputation: 630
Use this
if (preg_match('#\.(\.)?/#', $path, $match)) echo "Error";
If you need to check for ../ or ./ only in the beginning you must use this
if (preg_match('#^\.(\.)?/#', $path, $match)) echo "Error";
Upvotes: 0