Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure all files written are below a given path (prevent directory access)

We have a C# application which will write files to a configurable location. The set of files (and relative paths) is determined at runtime.

We want to ensure that it cannot write files outside the configured location.

For example, the configured location might be c:\Stuff\Export, it would be an error for the program to write anything under C:\Stuff\Important

Really, I think we can achieve this in two ways: 1) Assert none of the relative paths (files to be written) specify 'Parent directory' (typically "../") - System.Path doesn't specify a "parent directory" path component though (like it has for path separation i.e. System.Path.PathSeparator). I feel a bit cludgey checking for "../" in the string.

2) Assert that all of the final absolute paths that are generated (by combining the output location with the file relative path) are relative to i.e. underneath the output location. I'm not exactly sure how to go about this though.

Example usage:
Output directory: c:\Stuff\Export
Output path 1: "foo\bar\important.xls"
Output path 2: "foo\boo\something.csv"
Output path 3: "../../io.sys"

Expected final files
1. c:\Stuff\Export\foo\bar\important.xls
2. c:\Stuff\Export\foo\boo\something.csv
3. Should throw exception
like image 267
eddiewould Avatar asked Oct 18 '11 20:10

eddiewould


People also ask

Which of the following helps us to prevent a path traversal attack?

The Answer To prevent path traversal in your web server, update your web server and operating system to the latest versions available. This vulnerability has been known for a while, and it is likely your web server's latest version is not vulnerable.

How can you protect vs path traversal attacks?

The most effective way to prevent file path traversal vulnerabilities is to avoid passing user-supplied input to filesystem APIs altogether. Many application functions that do this can be rewritten to deliver the same behavior in a safer way.

What is file path traversal attack?

A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder.

What is a directory traversal attack with example?

The simplest example of a directory traversal attack is when an application displays or allows the user to download a file via a URL parameter.


2 Answers

If you create a DirectoryInfo instance on the two paths, its FullName property should return the fully qualified, canonical path. So if you just do that for both of the sides you want to compare, you can do this:

if (chosenDirectory.FullName != configuredDirectory.FullName)
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}

Since FullName is just a string, you can do regular string comparison on the paths, like:

if (!chosenDirectory.FullName.StartsWith(configuredDirectory.FullName,
    StringComparison.InvariantCultureIgnoreCase))
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}

You can also use the Parent property and compare its FullName to the chosen directory, if you don't want to allow sub-directories within the configured directory:

if (!chosenDirectory.Parent.FullName.Equals(configuredDirectory.FullName,
    StringComparison.InvariantCultureIgnoreCase))
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}
like image 145
Asbjørn Ulsberg Avatar answered Sep 28 '22 09:09

Asbjørn Ulsberg


Here's a quick solution:

string chroot = @"C:\root\child";
string requestedPath = @"..\";
string path = Path.GetFullPath(Path.Combine(chroot, requestedPath));
if (!path.StartsWith(chroot, StringComparison.Ordinal))
    throw new Exception("Oops, caught ya!");

edit: If you want to know if the given path is a valid directory: Directory.Exists(path)

like image 36
Candide Avatar answered Sep 28 '22 09:09

Candide