Вам не нужно вызывать htmlspecialchars()
и HTMLPurifier
для данных - у вас действительно есть только одна проблема, и это гарантирует, что URL не содержит SQL-инъекцию - mysqli_real_escape_string()
будет сортировать что.
В качестве альтернативы, если вы выводите данные на страницу / HTML (вместо того, чтобы использовать их в качестве заголовков перенаправления HTTP), вам нужно будет использовать htmlentities()
для защиты от XSS-данных, КОГДА ВЫ ВЫХОДИТЕ. Золотое правило - понимание контекста:
Кодировка сущности HTML подходит для
ненадежные данные, которые вы положили в
тело документа HTML, например
внутри тега. Это даже своего рода
работает для ненадежных данных, которые идут
в атрибуты, особенно если
вы религиозны об использовании цитат
вокруг ваших атрибутов. Но HTML
кодирование объектов не работает, если вы
положить ненадежные данные внутри
помечать где угодно или событие
атрибут обработчика, например onmouseover, или
внутри CSS или в URL. Так что даже если
вы используете метод кодирования сущности HTML
повсюду ты еще скорее всего
уязвимы для XSS. Вы ДОЛЖНЫ использовать
экранировать синтаксис для части HTML
документ, который вы помещаете ненадежные данные
в.
Подробную информацию о предотвращении XSS можно найти в OWASP .
Всегда лучше кодировать данные (против соответствующей атаки) непосредственно перед их использованием (т. Е. Escape-строки MySQL для ввода в базу данных, чтобы предотвратить SQLi, escape-строки HTML для вывода на экран, чтобы предотвратить XSS, а не оба одновременно). ). Это позволяет вам отслеживать поток данных через ваше приложение, и вы знаете, что все данные в базе данных готовы для любых целей. Если вы кодируете эти данные в формате HTML перед тем, как поместить их в БД, вам придется дешифровать их, например, перед использованием в качестве заголовка HTTP.
Если вам необходимо закодировать данные до того, как они попадут в базу данных, убедитесь, что имя столбца отражает это для будущих разработчиков / сопровождающих!
EDIT:
Согласно комментарию VolkerK, лучший способ предотвратить XSS при выводе URL-адреса - проверить протокол - если он не соответствует вашим разрешенным протоколам (возможно, http / https), отклоните его:
$url = 'http://hostname/path?arg=value#anchor';
$parsedUrl = parse_url( $url );
if( $parsedUrl['scheme'] != 'http' ) {
// reject URL
} else {
$url = mysqli_real_escape_string( $mysqli, $url );
$sql = "INSERT INTO table (url) VALUES ('$url')";
// insert query
}
Это имеет преимущество в предотвращении javascript:alert('xss')
атак в <a href="$url">
ситуациях. Запуск htmlentities()
на javascript:alert('xss')
не влияет (поскольку ограниченное подмножество символов, таких как <>
, не должно быть экранированного), поэтому злонамеренный пользователь сможет запустить JS в вашем домене.