TLDR: безопасно ли сериализовать массив $ _POST в файл и затем прочитать его обратно в переменную $ _POST по другому запросу или другому сценарию?
Я понимаю, что это необычно. Для этого есть причина, и потребовалось бы дюжина страниц текста, чтобы объяснить, почему я рассматриваю возможность сделать это в особом случае, по крайней мере, в то же время.
Процесс сваривания:
file_put_contents('sample.post', serialize($_POST));
$_POST = unserialize(file_get_contents('sample.post'));
У меня уже есть обширная фильтрация для фактического содержимого переменной post. Мой вопрос заключается в том, дает ли процесс сериализации и десериализации всего массива $ _POST злоумышленнику метод атаки.
В документе PHP написано: «Предупреждение. Не передавайте ненадежный пользовательский ввод функции unserialize (). Несериализация может привести к загрузке и выполнению кода из-за создания и автозагрузки объекта, и злоумышленник может использовать это».
Я нашел эти статьи, которые описывают этот метод атаки. Но они, похоже, зависят от того, сможет ли пользователь указать строку для прямой десериализации, т.е. IE unserialize ($ _ POST [‘value’]).
https://www.notsosecure.com/remote-code-execution-via-php-unserialize/
https://heine.familiedeelstra.com/security/unserialize
Правильно ли я понимаю, что пока я сериализую и десериализую, объекты не могут быть созданы в процессе десериализации, верно?
У меня сложилось впечатление, что массив $ _POST будет когда-либо содержать только строки (хотя я не смог найти это явно упомянутое в документации PHP).
Насколько я понимаю, даже если кто-то предоставит строку, соответствующую формату сериализованного объекта, она будет «сохранена» как строка во время сериализации с явной длиной (длиной в байтах). Таким образом, он будет назначен в виде строки при десериализации. Кажется, что, поскольку длины строк хранятся вместе с ними во время сериализации, вы не можете отделить структуру сериализованной строки от ввода, как вы могли бы с помощью SQL-инъекции. Я пытался обмануть некоторых недопустимых многобайтовых символов, но безуспешно. Однако я не в состоянии сделать это, и опытные хакеры могут это сделать — две разные вещи.
Я не мог найти ничего другого о других методах атаки.
Пожалуйста, дайте мне знать, если я что-то упустил! Я просто прочитал несколько комментариев, в которых говорилось: «Никогда не делай этого», поэтому я нервничаю, что что-то неправильно понимаю.
Я думаю, что без дальнейших атак невозможно отправить что-либо как переменную POST для использования unserialize()
Позвоните позже по вашему сценарию, но у других, возможно, есть идея. Это может быть проблемой, если в $ _POST есть что-то несериализуемое, но я думаю, что этого не произойдет. Что бы ни было в $ _POST, оно уже было в памяти один раз, так что при условии serialize()
а также unserialize()
работать правильно, должно быть безопасно делать что-то вроде
$serialized = serialize($userinput);
unserialize($serialized);
Тем не менее, вы сохраняете эти данные на диск между ними. Воспользовавшись другим недостатком и получив доступ к вашим файлам (или получив доступ «по проекту», как, например, сотрудники ИТ-отдела), злоумышленник может изменить сохраненные сериализованные данные и может провести там атаку. Таким образом, это, очевидно, будет уязвимым.
Так что это действительно риск, хотя, возможно, не очень высокий. Имейте в виду, что безопасность этого решения во многом зависит от безопасности вашего сохраненного сериализованного контента.
Других решений пока нет …