Угрозы безопасности, вызванные неанизированным пользовательским вводом, кроме инъекций XSS и SQL в PHP?
Инъекции XSS и SQL являются двумя основными угрозами безопасности при неанизированном вводе данных пользователем.
XSS может быть предотвращено (когда нет WYSIWYG) с помощью htmlspecialchars(), а внедрение SQL может быть предотвращено с помощью параметризованных запросов и связанных переменных.
Используя эти два метода, безопасно ли использовать весь неанизированный ввод?
4 ответа
Вы всегда должны учитывать контекст, в котором используются данные. Поскольку упомянутые функции и методы работают, только если они используются в соответствии с целью их использования. Это относится не только к HTML и SQL, но и к любому другому языку / контексту.
Что касается XSS, так как htmlspecialchars
экранирует специальные символы HTML <
, >
, &
, "
, а также '
с помощью ссылок на символы HTML он защитит вас, только если вы поместите данные в контекст HTML, где <
, >
, &
, "
, или же '
являются разделителями контекста, но они не помогут вам, если применяются другие разделители (например, значение атрибута HTML без кавычек или вы уже ввели другой контекст в HTML (например, значение атрибута HTML, которое рассматривается как код JavaScript, такой как on…
атрибуты события; или в элементах HTML, которые являются другим языком, например, <script>
, или же <style>
где применяются другие / дополнительные правила). Не говоря уже о так называемой XSS на основе DOM, где ввод обрабатывается не сервером, а клиентским JavaScript. Так что есть ситуации, в которых htmlspecialchars
не поможет тебе
Однако в отношении эмулированных или реально подготовленных операторов вы должны быть на безопасной стороне, так как уровень соединения с базой данных или СУБД позаботятся о правильной обработке данных. Если, конечно, вы все еще создаете инструкцию, которая будет подготовлена с использованием неправильно обработанных данных.
Вот лишь некоторые возможные проблемы, связанные с XSS и SQL-инъекцией:
- Раскрытие файла внешнего объекта XML через
simplexml_load_[file|string]()
: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing - Удаленное выполнение кода через
unserialize()
: http://www.exploit-db.com/exploits/22398/ - Выполнение команды через
system()
,popen()
, так далее strcmp()
обход с использованием массивов- ...так далее...
Это всегда зависит от того, где вы передаете пользовательский ввод и как его дезинфицировать. Например, всегда используйте PDO для операций SQL, потому что даже при правильном выходе злоумышленник может ввести код SQL без кавычек:
SELECT title, content FROM cms WHERE id = 1
Злоумышленник может изменить это на:
SELECT title, content FROM cms WHERE id = -1 UNION SELECT username AS title, password AS content from users LIMIT 1
Только в этом случае intval()
может помочь, и экранирование (mysql_real_escape_string, magic_quotes, addlashes и т. д.) не поможет вообще.
Также посмотрите здесь, пожалуйста: Эксплуатируемые функции PHP
SQL-инъекция - это всего лишь один из примеров более широкой угрозы внедрения кода. То есть любой случай, когда пользовательский ввод (или любой другой ненадежный контент) выполняется как код.
Это включает в себя такие вещи, как eval(), но также и несколько других векторов. Ответ от @thebod включает ссылку на отличный поток Stackru: эксплуатируемые функции PHP.
Даже SQL-инъекция не может быть решена на 100% с помощью параметров или экранирования. Оба эти метода помогают очистить отдельные значения в выражениях SQL. Вам также может понадобиться разрешить ввод данных пользователем для выбора таблиц, столбцов, ключевых слов SQL или целых выражений. Для них параметры и экранирование не помогают. Пример:
$sql = "SELECT * FROM mytable ORDER BY $sortcolumn $asc_or_desc";
В этом примере имя столбца для сортировки и направление (ASC
против DESC
) основаны на переменных. Были ли переменные установлены из доверенного ввода или параметры $_GET использовались дословно, что приводило к уязвимости SQL-инъекций?
Лучшим решением для этих случаев является белый список. То есть, взять пользовательский ввод, сравнить его со списком имен столбцов, которые разрешены для этого динамического запроса, и если пользовательский ввод не соответствует ни одному из этих предопределенных вариантов, либо произойдет сбой, либо используйте значение по умолчанию.
Используя эти методы, ваш пользовательский ввод по большей части уже очищен. Если вы хотите продвинуться дальше, вы можете выполнить проверку входных данных перед запуском кода SQL. Примером может служить проверка числа только числовой, проверка длины пользовательского ввода и т. Д.