Как убедиться, что все записанные файлы находятся ниже указанного пути (запретить доступ к каталогу) - PullRequest
5 голосов
/ 19 октября 2011

У нас есть приложение на C #, которое будет записывать файлы в настраиваемое местоположение.Набор файлов (и относительные пути) определяется во время выполнения.

Мы хотим убедиться, что он не может записывать файлы за пределами сконфигурированного местоположения.

Например, сконфигурированное местоположение может быть c: \ Stuff \ Export, для программы было бы ошибкойнаписать что-нибудь в C: \ Stuff \ Important

Действительно, я думаю, что мы можем достичь этого двумя способами: 1) Не указывать ни один из относительных путей (файлов, которые нужно записать), указать «Родительский каталог» (обычно)../ ") - System.Path не указывает компонент пути" родительский каталог "(как это имеет место для разделения пути, т.е. System.Path.PathSeparator).Я чувствую себя немного грязным, проверяя наличие "../" в строке.

2) Утверждение, что все окончательные абсолютные пути, которые сгенерированы (путем объединения выходного местоположения с относительным путем файла) относительно, т. Е. Ниже выходного местоположения .Я не совсем уверен, как это сделать, хотя.

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

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

Вот быстрое решение:

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: Если вы хотите узнать, является ли данный путь допустимым каталогом: Directory.Exists(path)

4 голосов
/ 19 октября 2011

Если вы создаете экземпляр DirectoryInfo по двум путям, его свойство FullName должно возвращать полностью определенный канонический путь.Поэтому, если вы просто сделаете это для обеих сторон, которые хотите сравнить, вы можете сделать это:

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

Поскольку FullName - это просто строка, вы можете проводить обычное сравнение строк на путях, например:

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

Вы также можете использовать свойство Parent и сравнить его FullName с выбранным каталогом, если вы не хотите разрешать подкаталоги в настроенномкаталог:

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