Плохие новости
К сожалению, предотвращение XSS в PHP - нетривиальное мероприятие.
В отличие от SQL-инъекция , которую вы можетеСмягчить с помощью подготовленных заявлений и тщательно отобранных белых списков, невозможно обеспечить надежный способ отделить информацию, которую вы пытаетесь передать в ваш HTML-документ, от остальной части структуры документа.
Хорошие новости
Однако вы можете смягчить известные векторы атак, проявляя особую осторожность с выходом из системы ( и поддерживая программное обеспечение в актуальном состоянии ).
Самое важное правило, о котором следует помнить: Всегда экранировать на выходе, никогда на входе. Вы можете безопасно кэшировать экранированный выход, если вы беспокоитесь о производительности, но всегда сохраняете и работаете с неэкранированными данными.
Стратегии смягчения последствий XSS
В порядке предпочтения:
- Если вы используете шаблонизатор (например, Twig, Smarty, Blade), убедитесь, что он предлагает контекстно-зависимыйЭто убегает.По опыту я знаю, что это делает Твиг.
{{ var|e('html_attr') }}
- Если вы хотите разрешить HTML, используйте Очиститель HTML .Даже если вы думаете, что принимаете только Markdown или ReStructuredText, вы все равно хотите очистить HTML, выводимый этими языками разметки.
- В противном случае используйте
htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)
и убедитесь, что в остальной части документа используется тот же набор символов, что и $charset
.В большинстве случаев 'UTF-8'
является желаемым набором символов.
Почему я не должен фильтровать на входе?
Попытка отфильтровать XSS на входе преждевременная оптимизация , что может привести к неожиданным уязвимостям в других местах.
Например, недавняя уязвимость WordPress XSS использовала усечение столбцов MySQL, чтобы нарушить их стратегию побега и позволить преждевременно сбежавшей полезной нагрузке бытьхранится небезопасно.Не повторяйте их ошибку.