How to ensure that all recorded files are below a specified path (prohibiting directory access)

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

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

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

Indeed, I think that we can achieve this in two ways: 1) Do not specify any of the relative paths (files that need to be written) indicate "parent directory" (usually "../"). System.Path does not indicate the path component "parent directory" (for example, it has to separate paths ie System.Path.PathSeparator). I feel a little awkward checking the "../" on the line.

2) Make sure that all final absolute paths that are generated (by combining the output location with the relative path of the file) refer to i, that is, below the output location. I'm not quite sure how to do this.

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 
+4
source share
2 answers

If you create an instance of DirectoryInfo for two paths, its FullName property should return a fully qualified canonical path. Therefore, if you just do it for both sides that 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 perform regular string comparisons along paths, for example:

 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 with the selected directory if you do not want to allow subdirectories in the configured directory:

 if (!chosenDirectory.Parent.FullName.Equals(configuredDirectory.FullName, StringComparison.InvariantCultureIgnoreCase)) { throw new InvalidOperationException( String.Format("Invalid path {0}.", chosenDirectory)); } 
+4
source

Here's a quick fix:

 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 a given path is a valid directory: Directory.Exists(path)

+4
source

All Articles