Luke Vo
Luke Vo

Reputation: 20648

Validate to prevent a path string to go up to parent folder

My business logic is accepting a folder path string to read a folder/file. However as security dictates, the user can only access that folder. For example:

Their folder is: C:\foo\user\bar, they can access C:\foo\user\bar\data\.a.b..txt by https://www.example.com/download?path=data/.a.b..txt

However, I want to prevent user from entering something that could make them go up a folder and see data of other. Here is my current code:

        var result = this.ResultFolder; // The user folder (\user\bar as in the example)

        if (!string.IsNullOrEmpty(path))
        {
            path = path.Replace("/", @"\");

            if (path.StartsWith(@"\"))
            {
                path = path.Substring(1);
            }

            if (path.StartsWith('\\') || path.Contains("..\\"))
            {
                throw new InvalidDataException("Forbidden Path.");
            }

            result = Path.Combine(result, path);
        }

Basically, what I do:

Is it correct and safe yet? Is there any framework method that helps with this?

Upvotes: 2

Views: 1016

Answers (1)

Flydog57
Flydog57

Reputation: 7111

Here's a solution that uses Path.GetFullPath(string path):

Create this function:

private static bool VerifyPathUnderRoot(string pathToVerify, string rootPath = ".")
{
    var fullRoot = Path.GetFullPath(rootPath);
    var fullPathToVerify = Path.GetFullPath(pathToVerify);
    return fullPathToVerify.StartsWith(fullRoot);
}

Then you can test it with code like this:

 var paths = new[]
 {
     "somepath/somefile.xxx",
     "..\\somepath/somefile.xxx",
     @"C:\this\that\the.other",
 };
 foreach (var path in paths)
 {
     var isOk = VerifyPathUnderRoot(path);
     var okString = isOk ? "OK" : "No";
     Debug.WriteLine($"{okString}: {path}");
 }

which results in this in the Output pane of the debugger:

OK: somepath/somefile.xxx
No: ..\somepath/somefile.xx
No: C:\this\that\the.other

I use GetFullPath twice to canonicalize the paths (making sure that all slashes end up the same, etc.).

Upvotes: 2

Related Questions