Может ли вредоносное вступление в файл записываться в файл?

Простой пример Uber для иллюстрации:

$message = $_POST['message']; $fp = fopen("log.txt", "a"); fwrite($fp, $message); fclose($fp); 

Должен ли я дезинформировать ввод пользователя для переменной $_POST['message'] ?

Я понимаю подготовленные заявления (для дезинфекции базы данных) и htmlentities (если я htmlentities сообщение POST на экран в какое-то время), но в этом случае вход просто сидит в файле журнала, который будет читаться небольшим скриптом PHP ( via fopen() )

Ответ зависит от того, как он будет читаться? Например, если я открываю файл журнала через fopen (), он должен быть htmlentities , и если я планирую загрузить файл журнала и прочитать его с помощью Excel (для целей фильтрации), ничего не поделаешь?

Solutions Collecting From Web of "Может ли вредоносное вступление в файл записываться в файл?"

Ваш код в основном невиновен. Единственной «очевидной» атакой будет повторная загрузка данных на ваш сервер, что в конечном итоге приведет к исчерпанию дискового пространства.

«дезинфекция» – это нечто ситуативное. Это не то, что вы можете просто побрызгать кодом, чтобы сделать его лучше, как вы можете с солью на еде. Возможно, вы будете дезинфицировать данные $ _POST для предотвращения атак SQL-инъекций, но затем использовать данные в контексте HTML – теперь вы уязвимы для атак XSS. Возможно, это загрузка изображения, и вы выполняете базовое определение типа MIME, чтобы убедиться, что это изображение. Это все хорошо и денди, но потом кто-то загружает Kiddy порно, который будет проходить «это изображение» тест, и теперь у вас есть гораздо более серьезная проблема.

Поскольку вы принимаете данные пользователя и записываете его в файл, с этим кодом (кроме проблемы с дисковым пространством) ничего не может быть сделано для злоупотребления вашей системой. Вы не можете внедрить некоторую последовательность данных в данные, которые заставили бы PHP или базовую ОС внезапно прекратить записывать эти данные на диск и начать его выполнение. Не имеет значения, КАК вид, если данные загружаются, потому что он никогда не используется в контексте, где он может использоваться для воздействия на выполнение скрипта. Вы просто всасываете некоторые данные с веб-сервера и выплевываете их на диск. Вы не позволяете пользователю влиять на файл, на который написан (если только у ваших пользователей нет доступа к серверу на уровне оболочки, и он может, например, создать символическую ссылку, называемую «log.txt», указывая на какой-то другой более критический файл).

Реальная проблема возникает после … что вы делаете с этим файлом после его написания? Если ваш более поздний код делает что-то глупое

 include('log.txt'); 

то теперь у вас есть проблема – вы теперь взяли эти «невинные» данные, сидящие в файле на диске и превратив их в потенциально исполняемый код. Все, что требуется, – это простой <?php exec('rm -rf /') ?> любом месте этого файла, чтобы удалить ваш сервер.

Кроме того, рассмотрите что-то вроде неотъемлемо идиотской меры безопасности, которая была magic_quotes PHP. Разработчики PHP ( WRONGLY и STUPIDLY ) предполагали, что ЛЮБЫЕ данные, представленные из внешнего мира, будут использоваться только в контексте SQL и будут выполняться SQL на всех данных независимо от их конечной цели. И чтобы сделать это хуже, они просто предположили, что все базы данных используют обратную косую черту для их escape-последовательности. Все в порядке и денди, если вы никогда не используете ничего, кроме MySQL, но что, если вы на, скажем, SQL Server? Теперь вам нужно перевести предоставленный PHP Miles O\'Brien в Miles O''Brien , по сути имея для UNDO то, что PHP сделал для вас автоматически.

TL; DR: Не используйте методы дезинфекции дробовика, они почти всегда бесполезны / бессмысленны и просто требуют больше работы до И после. Просто используйте контекстные методы во время использования данных.

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

Вам не нужно беспокоиться о функциях чтения / записи PHP, таких как fopen (). Будьте внимательны с шагами, которые фактически анализируют или анализируют ввод. Некоторые возможные примеры:

  • Если файл будет отображаться в основном лог-ридере, вам может потребоваться убедиться, что каждый вход ограничен определенной длиной и не содержит разрывов строк или выбранного вами разделителя поля, а начало каждой строки является допустимым временем печать.
  • Если файл будет отображаться в веб-браузере, вам может потребоваться убедиться, что входы не содержат скриптов или ссылок на другие ресурсы (например, IMG-тег).
  • Файлы Excel будут иметь схожие проблемы относительно длины строки, временных меток и разделителей. Вам не нужно беспокоиться о ком-то, включая исполняемый код, пока Excel будет анализировать файл как текст. (Кроме того, современные версии Excel дают вам предупреждения о включенных макросах перед их запуском.)

Общее правило заключается в проверке ввода и дезинфекции вывода .

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

например, если вы знаете, что каждое message должно быть меньше 100 символов, независимо от того, как оно используется , скрипт, который считывает данные POST, может проверять и отклонять любой запрос, данные POST которого содержат ввод, который составляет 100 символов или более.

Валидация – это подход «все или ничего», который отвергает все, что не соответствует определенным правилам, независимо от контекста вывода, тогда как санитария – это процесс «создания чего-то безопасного» в зависимости от контекста. Я думаю, что важно сделать это различие.

В вашем случае примерный код, который вы предоставили, не выводится (кроме пупок для обработки другим скриптом). Это скорее операция хранения, чем операция вывода, поскольку message может быть записано в базу данных так же легко, как и файловая система. Основной поверхностью атаки, которая должна была блокироваться в этом случае, является разрешение на доступ к файлам и удостоверение, что ничто не может читать или записывать в файл, кроме сценариев, которые вы намереваетесь сделать, и в правильном контексте. Например, я понимаю, что ваш пример был упрощен, но в этом конкретном случае вы должны убедиться, что файл написан в месте, расположенном выше вашего веб-корня, или в том месте, где установлены права доступа к папке. В противном случае у вас может быть непреднамеренно предоставлен доступ для любого пользователя в Интернете, чтобы прочитать http://www.example.com/log.txt, и если они могут писать на него, возможно, будет возможно использовать какую-либо атаку XSS, если они могут обмануть браузер в чтение файла как HTML. Старые версии Internet Explorer пытаются обнаружить MIME-тип, а не полагаться на значение заголовка сервера text/plain (см. Также здесь ). Однако эти уязвимости могут быть слегка отключены от темы, и я просто упомянул их, чтобы они были тщательными и как пример обеспечения того, чтобы сами файлы были заблокированы соответствующим образом.

Вернемся к вашему вопросу: в вашем случае ваша проверка должна выполняться скриптом, который обрабатывает log.txt . Это должно проверить файл. Обратите внимание, что он проверяет файл здесь, а не сырое message . Файл должен быть проверен с использованием его собственных правил, чтобы убедиться, что данные как ожидалось. Если сценарий напрямую выводит что-либо, это место, где должна произойти санитария, чтобы соответствовать контексту выхода. Таким образом, для обобщения процесса валидации и санитарии для вашей заявки будет:

  1. Создать журнал: веб-браузер — POST —> get_message.php —> проверить правильность messagefwrite() -> log.txt

  2. log.txt процесса: log.txtfopen() —> process.php —> проверить, что файл действителен —> что-нибудь выводит? затем санировать на этом этапе.

Вышеприведенное предполагает, что правильная авторизация выполняется до того, как обработка выполняется сценариями (то есть, что текущий пользователь имеет разрешения в вашем приложении для регистрации message или журналов процессов).

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

Взгляните на Injection Log Attack

Также будьте очень осторожны при отображении файла журнала. Убедитесь, что выходной сигнал не повредит читателю.

  • Вы добавляете к файлу в текущем каталоге – это, кажется, загружается через браузер, поэтому вы создаете дыру в безопасности. Поместите файл за пределы корня документа (лучше всего) или защитите его через .htaccess.
  • Вы должны дезинформировать все входные данные пользователя. Всегда. Это означает, что вы используете эти данные. Кажется, вы пишете текстовый файл журнала, поэтому вам нужно будет пропускать только символы печати и пробелов. Санитировать в обороне: НЕ указывать плохие символы и пропускать все остальное, но определять список / классы «хороших» символов и просто пропускать эти хорошие символы.
  • В зависимости от вашего варианта использования вы можете захотеть скопировать () файл журнала, чтобы предотвратить смешение нескольких параллельных запросов в вашем файле:

    $ logtext = sanitizeLog ($ _ POST [Message]); $ fd = fopen ("/path/to/log.txt", "a"); if (flock ($ fd, LOCK_EX)) {fseek ($ fd, 0, SEEK_END); fwrite ($ fd, $ logtext); flock ($ fd, LOCK_UN); } fclose ($ fd);

Я пропустил проверки для результатов fopen () …

Что касается функции fwrite () PHP, нет необходимости санировать : fwrite () просто записывает это в файл, который он передает.

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

Предположим, что злоумышленник отправил сообщение с несколькими строками в виде сообщения. Если ваш журнал был до публикации

 line 1 line 2 

то это после публикации

 line 1 line 2 line 3 remainder of line 3 very remainder of line 3 

потому что злоумышленник опубликовал это:

 line 3\nremainder of line 3\nvery remainder of line 3 

Примечание: добавлено одно время против 3 строк.

Это сказало: как данные должны быть подвергнуты санитарной обработке, полностью зависит от вашего приложения.