Я воспользовался уязвимостью в первой десятке OWASP и обнаружил, что Cross-Site Scripting - это тот, который мы должны делать. Было несколько рекомендованных решений. Один из них заявил, что не используйте проверку "черного списка" для обнаружения XSS во вводе или для кодирования вывода. Поиск и замена всего нескольких символов (<
и >
и других похожих символов или фраз, таких как script
) слабый и успешно атакован. Даже непроверенный тег "<b>"
небезопасен в некоторых контекстах. XSS имеет удивительное количество вариантов, которые упрощают обход проверки черного списка. В другом решении говорилось, что сильное кодирование вывода. Перед представлением убедитесь, что все предоставленные пользователем данные соответствующим образом кодируются сущностью (либо HTML, либо XML в зависимости от механизма вывода). Итак, что является лучшим способом предотвращения межсайтового скриптинга для проверки и замены ввода или кодирования вывода?
Рекомендации Java по предотвращению сценариев Cross Site
Ответ 1
Обычная практика заключается в том, что HTML-escape контролируемых пользователем данных во время повторного отображения в JSP, а не во время обработки представленных данных в сервлете или во время хранения в БД. В JSP вы можете использовать JSTL (чтобы установить его, просто снимите jstl-1.2.jar в /WEB-INF/lib
) <c:out>
или fn:escapeXml
. Например.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<p>Welcome <c:out value="${user.name}" /></p>
и
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input name="username" value="${fn:escapeXml(param.username)}">
Что это. Нет необходимости в черном списке. Обратите внимание, что данные, управляемые пользователем, охватывают все, которые входят в HTTP-запрос: параметры запроса, тело и заголовки (!!).
Если вы выходите из HTML во время обработки представленных данных и/или сохраняете их в БД, то все они распространяются по бизнес-коду и/или в базе данных. Это только проблема технического обслуживания, и вы будете рисковать двойными экранами или больше, когда вы делаете это в разных местах (например, &
станет &amp;
вместо &
, чтобы enduser буквально увидел &
вместо &
бизнес-код и БД, в свою очередь, не чувствительны к XSS, а только вид. Вы должны избегать этого только прямо там.
См. также:
Ответ 2
Используйте оба параметра. На самом деле обратитесь к руководству, например, к OWASP ESAPI о том, как выходные кодеры и сертификаторы ввода записываются в библиотеке безопасности.
Ответ 3
Мое предпочтение состоит в том, чтобы кодировать все неамериканские символы как числовые символьные символы HTML. Поскольку почти, если не все атаки требуют не-алфавитных символов (например, <, "и т.д.), Это должно исключать большую часть опасного вывода.
Формат is & #N;, где N - числовое значение символа (вы можете просто передать символ в int и объединить со строкой, чтобы получить десятичное значение). Например:
// java-ish pseudocode StringBuffer safestrbuf = new StringBuffer(string.length()*4); foreach(char c : string.split() ){ if( Character.isAlphaNumeric(c) ) safestrbuf.append(c); else safestrbuf.append(""+(int)symbol);
Вам также необходимо быть уверенным, что вы кодируете непосредственно перед выходом в браузер, чтобы избежать двойного кодирования или кодирования для HTML, но отправляйте в другое место.