У многих файлов тактика есть проблема безопасности обхода каталога? - PullRequest
2 голосов
/ 11 июня 2009

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

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

создайте множество id-файлов и используйте их ScanDir.

поэтому в каталоге будет

aaa.txt (содержимое aaa_pass)
bbb.txt (содержимое bbb_pass)
ccc.txt (содержимое ccc_pass)

и когда кто-то вводит его идентификатор,
система scandir каталог,
затем найдите файлы идентификаторов.

но эй, что если он введет как

"../../ важный.txt"?

тогда он сможет получить доступ к ../../important.txt?

Ответы [ 3 ]

2 голосов
/ 11 июня 2009

На первый взгляд кажется, что вы идете по несколько странному пути написания системы входа в систему. Я не уверен, что простые текстовые файлы в каталоге в файловой системе - это разумный путь, если не по какой-либо другой причине, кроме как ненормальной, и вы, скорее всего, пропустите многие тонкости, которые уже продуманы при более распространенной аутентификации системы. Например, если вы хотите хранить хэшированные и соленые пароли, вам нужно подумать о том, как реализовать это в вашей схеме, и вы можете ошибиться, что приведет к проблеме безопасности. Однако использование хорошей библиотеки PEAR или даже компонента Zend_Auth из Zend Framework даст вам четкую и хорошо документированную отправную точку.

В любом случае, если у вас есть причины для соглашения, которое вы описываете в своем вопросе, функция basename (), скорее всего, то, что вам нужно в этом случае. Он удалит все, кроме имени файла, так что они не смогут атаковать каталог, как вы описали в своем вопросе.

Так что, если ввод от пользователя:

.. / .. / важный

Вы можете запустить:

$cleanUsername = basename($input);
$filename      = '/path/to/password/files/' . $cleanUsername . '.txt';

if (file_exists($filename)) {
    [...]
}

Имеет смысл?

1 голос
/ 11 июня 2009

Если у вас нет другого выбора, кроме как использовать эту систему файлов-паролей (при условии, что вам придется по той или иной причине), в дополнение к созданию какого-либо запутанного имени файла, вы можете также захотеть создать файлы с тем же расширением как ваш серверный язык на всякий случай - например, если вы используете PHP, имя вашего файла будет john.php (или обфусцированный 'john'), а содержимое может выглядеть примерно так:

<?php
    exit; // or maybe even a header redirect --
    /*password goes here*/
?>

Конечно, ваша процедура чтения файлов должна будет проанализировать нашу фразу внутри блока комментариев.

Таким образом, если кто-то каким-то образом получит этот файл, он никогда не будет отображаться.

1 голос
/ 11 июня 2009

Вы можете выполнить некоторую проверку имени пользователя, прежде чем использовать его как часть пути - например, чтобы разрешить только буквы и цифры, вы можете сделать что-то подобное, используя регулярное выражение:

if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) {
    //username is not valid
} else {
    //username is ok to use
}

Другой способ сделать это - хэшировать имя пользователя перед тем, как вы его прочитаете или напишите, например:

$hash = sha1($username);

Таким образом, у пользователя может быть что угодно в качестве имени пользователя, и не будет никакой опасности, что он будет манипулировать поведением поиска вашего файла. Имя пользователя "../../important.txt" даст вам хэш "48fc9e70df592ccde3a0dc969ba159415c62658d", который является безопасным, несмотря на то, что исходная строка неприятна.

...