Безопасная функция очистки XSS (регулярно обновляется)

Я уже несколько дней охочусь за сетью, пытаясь понять это, но получаю противоречивые ответы.

Есть ли библиотека, класс или функция для PHP, которая надежно защищает / кодирует строку против XSS? Он должен регулярно обновляться, чтобы противостоять новым атакам.

У меня есть несколько вариантов использования:

Случай использования 1) У меня есть текстовое поле, например, для имени или фамилии

  • Пользователь вводит текст в поле и представляет форму
  • Перед тем, как это будет сохранено в базе данных, я хочу: а) обрезать любые пробелы перед фронтом и концом строки и b) отделить все теги HTML от ввода. Это текстовое поле с именем, в нем не должно быть никакого HTML-кода.
  • Затем я сохраню это в базе данных с подготовленными инструкциями PDO.

Я думаю, что могу просто сделать trim() и strip_tags() затем использовать фильтр Sanitize или RegEx со списком символов. Им действительно нужны персонажи! а также ? или < > в их имени, на самом деле.

Случай использования 2) При выводе содержимого из ранее сохраненной записи базы данных (или из ранее представленной формы) в представление / HTML я хочу полностью очистить ее для XSS. NB: Возможно, он прошел или не прошел этап фильтрации в прецеденте 1, поскольку он может быть другим типом ввода, поэтому не предполагайте, что никакая дезинфекция не была выполнена.

Первоначально я, хотя HTMLPurifier выполнял эту работу, но, как мне кажется, это не то, что мне нужно, когда я задавал вопрос своей поддержке :

Вот тест лакмусовой бумажки: если пользователь отправляет <b>foo</b> если он отображается как <b>foo</b> или foo ? Если первый, вам не нужен очиститель HTML.

Поэтому я предпочел бы, чтобы он отображался как <b>foo</b> потому что я не хочу, чтобы какой-либо HTML отображался для простого текстового поля или любого исполняемого кода JavaScript.

Поэтому я охотился за функцией, которая сделает все это для меня. Я наткнулся на метод xss_clean, используемый Kohana 3.0, который, как я предполагаю, работает, но это только если вы хотите сохранить HTML. Теперь он устарел от Kohana 3.1, поскольку они заменили его на HTMLPurifier. Поэтому я предполагаю, что вы должны делать HTML::chars() вместо этого, который только делает этот код :

 public static function chars($value, $double_encode = TRUE) { return htmlspecialchars( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode); } 

Теперь, очевидно, вы должны использовать htmlentities вместо этого, как упоминалось в довольно многих местах в Stack Overflow, потому что он более безопасен, чем htmlspecialchars.

  • Итак, как правильно использовать htmlentities?
  • Это все, что мне нужно?
  • Как он защищает от кодирования шестнадцатеричных, десятичных и base64 значений, отправленных из перечисленных здесь атак?

Теперь я вижу, что третий параметр для метода htmlentities – это кодировка, которая будет использоваться при преобразовании. Теперь мой сайт / db находится в UTF-8, но, возможно, данные, представленные в форме, не были закодированы в кодировке UTF-8, возможно, они отправили ASCII или HEX, поэтому, возможно, мне нужно сначала преобразовать ее в UTF-8? Это означало бы какой-то код вроде:

 $encoding = mb_detect_encoding($input); $input = mb_convert_encoding($input, 'UTF-8', $encoding); $input = htmlentities($input, ENT_QUOTES, 'UTF-8'); 

Да или нет? Тогда я все еще не уверен, как защитить от шестнадцатеричных, десятичных и base64 возможных входов XSS …

Если есть какая-то библиотека или PHP с открытым исходным кодом, которая может правильно защитить XSS, мне было бы интересно увидеть, как они это делают в коде.

Любая помощь очень ценится, извините за длинный пост!

Чтобы ответить на смелый вопрос: Да, есть. Это называется htmlspecialchars .

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

Правильный способ предотвратить атаки XSS – это не противодействие конкретным атакам, фильтрация / дезинфекция данных, а правильная кодировка везде.

htmlspecialchars (или htmlentities ) в сочетании с разумным решением кодирования символов (например, UTF-8 ) и явной спецификацией кодировки символов является достаточным для предотвращения всех атак XSS. К счастью, вызов htmlspecialchars без явного кодирования (тогда он предполагает, что ISO-8859-1) тоже будет работать для UTF-8. Если вы хотите сделать это явным, создайте вспомогательную функцию:

 // Don't forget to specify UTF-8 as the document's encoding function htmlEncode($s) { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); } 

О, и обратиться к форме беспокоиться: не пытайтесь обнаружить кодировки, она обязательно потерпит неудачу. Вместо этого выдать форму в UTF-8. Затем каждый браузер будет отправлять пользовательские входы в UTF-8.

Решение конкретных проблем:

(…) вы должны использовать htmlentities, потому что htmlspecialchars уязвим для эксплойта UTF-7 XSS.

Эксплуатация UTF-7 XSS может применяться только в том случае, если браузер считает, что документ закодирован в UTF-7. Указание кодировки документа как UTF-8 (в заголовке HTTP / метатеге сразу после <head> ) предотвращает это.

Кроме того, если я не обнаружил кодировку, то что должно остановить атакующего, загружающего html-файл, а затем изменив его на UTF-7 или какую-либо другую кодировку, а затем отправив запрос POST обратно на мой сервер с измененной страницы html?

Этот сценарий атаки излишне сложный. Злоумышленник может просто создать строку UTF-7, не нужно ничего загружать.

Если вы принимаете POST злоумышленника (то есть вы принимаете анонимный публичный пользовательский ввод), ваш сервер будет просто интерпретировать строку UTF-7 как странный UTF-8. Это не проблема, сообщение злоумышленника просто покажется искаженным. Злоумышленник мог добиться такого же эффекта (отправка странного текста), отправляя «grfnlk» сто раз.

Если мой метод работает только для UTF-8, то XSS-атака пройдет, нет?

Нет, не будет. Кодировки не являются волшебными. Кодировка – это всего лишь способ интерпретировать двоичную строку. Например, строка «ö» кодируется как (шестнадцатеричная) 2B 41 50 59 в UTF-7 (и C3 B6 в UTF-8). Декодирование 2B 41 50 59 как UTF-8 дает «+ APY» – безвредные, казалось бы, случайные персонажи.

Также как htmlentities защищают от HEX или других атак XSS?

Шестнадцатеричные данные будут выводиться именно так. Злоумышленник, отправляющий «3C», отправит сообщение «3C». «3C» может стать только < если вы активно пытаетесь интерпретировать шестнадцатеричные входы в противном случае, например, активно сопоставляете их в кодовые точки юникода, а затем выводите их. Это просто означает, что если вы принимаете данные во что-то, кроме простого UTF-8 (например, UTF-8 с кодировкой base32), вам сначала придется распаковать кодировку, а затем использовать htmlspecialchars прежде чем включать ее между HTML-кодом.

Многие инженеры по безопасности рекомендуют использовать эту библиотеку для этой конкретной проблемы:

https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API