Давайте посмотрим на лес сначала, прежде чем смотреть на деревья.
Здесь есть много информативных ответов с большими подробностями, я не буду повторять ни одного из них. Ключ к программированию в JavaScript имеет сначала правильную ментальную модель общего исполнения.
Хорошие новости заключается в том, что, если вы хорошо понимаете этот момент, вам никогда не придется беспокоиться о гоночных условиях. Прежде всего вы должны понимать, как вы хотите упорядочить свой код как по существу ответ на разные дискретные события, и как вы хотите объединить их в логическую последовательность. Вы можете использовать обещания или новые асинхронные / ожидающие более высокие уровни в качестве инструментов для этой цели, или вы можете откатывать свои собственные.
Но вы не должны использовать какие-либо тактические инструменты для решения проблемы, пока вам не понравится актуальная проблемная область. Нарисуйте карту этих зависимостей, чтобы знать, что нужно запускать, когда. Попытка ad-hoc подхода ко всем этим обратным вызовам просто не поможет вам.
XSS можно предотвратить в JSP с помощью JSTL <c:out>
тега или fn:escapeXml()
Функция EL, когда (повторно) управляемый вход. Сюда входят параметры запроса, заголовки, файлы cookie, URL, тело и т. Д. Все, что вы извлекаете из объекта запроса. Кроме того, пользовательский управляемый вход из предыдущих запросов, который хранится в базе данных, должен быть экранирован во время повторного отображения.
Например:
<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>
Это приведет к выходу символов, которые могут отобразили HTML, такие как <
, >
, "
, '
и &
в объекты HTML / XML , такие как <
, >
, "
, '
и &
.
Обратите внимание, что вам не нужно избегать их в коде Java (Servlet), так как они безвредны там. Некоторые могут отказаться от них во время обработки запроса (как вы это делаете в Servlet или Filter) вместо обработки response (как и в JSP), но таким образом вы можете рискнуть что данные без необходимости получают двойное экранирование (например, &
становится &amp;
вместо &
, и в конечном итоге конечный пользователь увидит &
) или что данные, хранящиеся в базе данных, становятся недоступными (например, при экспорте данных в JSON, CSV, XLS, PDF и т. Д., Которые вообще не требуют HTML-экранирования). Вы также потеряете социальный контроль, потому что вы больше не знаете, что пользователь действительно заполнил. Вы, как администратор сайта, действительно хотели бы знать, какие пользователи / IP-адреса пытаются выполнить XSS, чтобы вы могли легко отслеживать их и принять соответствующие меры. Эвакуация во время обработки запроса должна использоваться и использоваться только в качестве последнего курорта, когда вам действительно нужно как можно скорее исправить крушение поезда плохо разработанного старого веб-приложения в кратчайшие сроки. Тем не менее, вы должны в конечном счете переписать свои JSP-файлы, чтобы они стали XSS-безопасными.
Если вы хотите повторно отобразить управляемый пользователем ввод как HTML, в котором вы хотели бы разрешить только определенный поднабор HTML-тэгов, например <b>
, <i>
, <u>
и т. д., тогда вам нужно дезинформировать входные данные с помощью белого списка. Для этого можно использовать парсер HTML, например Jsoup . Но гораздо лучше ввести дружественный человеку язык разметки, такой как Markdown (также используемый здесь в Stack Overflow). Для этого вы можете использовать анализатор Markdown, например CommonMark . Он также встроил средства для очистки HTML. См. Также Я ищу Java-кодер Java .
Единственной проблемой на стороне сервера в отношении баз данных является предотвращение SQL injection . Вы должны убедиться, что вы никогда не связываете строки с пользовательским контролем прямо в запросе SQL или JPQL и что вы используете параметризованные запросы полностью. В терминах JDBC это означает, что вместо Statement
вы должны использовать PreparedStatement
. В терминах JPA используйте Query
.
Альтернативой может быть переход из JSP / Servlet в Java MVC framework JSF . Он имеет встроенную поддержку XSS (и CSRF!) По всему месту. См. Также Предотвращение атаки CSRF, XSS и SQL Injection в JSF .
Если вы хотите автоматически избежать всех переменных JSP без явного переноса каждой переменной, вы можете использовать EL resolver , как подробно описано здесь, с полным источником и примером (JSP 2.0 или новее) и более подробно здесь :
Например, используя вышеупомянутый EL-резольвер, ваш JSP-код останется таким же, но каждая переменная будет автоматически экранирована с помощью распознавателя
...
<c:forEach items="${orders}" var="item">
<p>${item.name}</p>
<p>${item.price}</p>
<p>${item.description}</p>
</c:forEach>
...
Если вы хотите принудительно экранировать по умолчанию весной, вы тоже можете это рассмотреть, но это не исключает выражения EL, просто вывод тега, я думаю:
http://forum.springsource.org/showthread.php?61418-Spring-cross-site-scripting&p=205646#post205646
Примечание. Еще один подход к экранированию EL который использует преобразования XSL для препроцессов JSP-файлов, можно найти здесь:
http://therning.org/niklas/2007/09/preprocessing-jsp-files-to-automatically-escape-el -expressions /
В XSS нет простого решения из коробки. API OWASP ESAPI поддерживает некоторую поддержку, которая очень полезна, и у них есть библиотеки тегов.
Мой подход состоял в основном в расширении тегов stuts 2 следующими способами.
Если вы не использовали ' t хотите изменить классы на шаге 1, другим подходом было бы импортировать теги ESAPI в шаблоны freemarker и, при необходимости, бежать. Затем, если вам нужно использовать как: тег свойства в вашем JSP, оберните его и тегом ESAPI.
Я написал более подробное объяснение здесь.
http: / /www.nutshellsoftware.org/software/securing-struts-2-using-esapi-part-1-securing-outputs/
Я согласен с тем, что выходные данные не идеальны.
Мне повезло с OWASP Anti-Samy и советником AspectJ на всех моих контроллерах Spring, которые блокируют XSS от входа.
public class UserInputSanitizer {
private static Policy policy;
private static AntiSamy antiSamy;
private static AntiSamy getAntiSamy() throws PolicyException {
if (antiSamy == null) {
policy = getPolicy("evocatus-default");
antiSamy = new AntiSamy();
}
return antiSamy;
}
public static String sanitize(String input) {
CleanResults cr;
try {
cr = getAntiSamy().scan(input, policy);
} catch (Exception e) {
throw new RuntimeException(e);
}
return cr.getCleanHTML();
}
private static Policy getPolicy(String name) throws PolicyException {
Policy policy =
Policy.getInstance(Policy.class.getResourceAsStream("/META-INF/antisamy/" + name + ".xml"));
return policy;
}
}
Вы можете получить советника AspectJ из этого stackoverflow post
Я думаю, что это лучший подход, тогда c: вне, если вы делаете много javascript.
Для управления XSS требуется несколько проверок, данные с клиентской стороны.
Я предлагаю регулярно тестировать уязвимости с помощью автоматизированного инструмента и фиксировать все, что он находит. Гораздо проще предложить библиотеку, чтобы помочь с определенной уязвимостью, а затем для всех атак XSS в целом.
Skipfish - это инструмент с открытым исходным кодом от Google, который я изучал : он находит довольно много вещей и, кажется, стоит использовать.
Несколько раз попробовато как-предупредить-xss. В StackOverflow вы найдете много информации. Кроме того, на веб-сайте OWASP есть защитный чит XSS , который вы должны пройти.
В библиотеках, которые будут использоваться, Библиотека ESAPI OWASP имеет java-вкус , Вы должны попробовать это. Кроме того, каждая используемая вами инфраструктура имеет некоторую защиту от XSS. Опять же, веб-сайт OWASP содержит информацию о большинстве популярных фреймворков, поэтому я бы рекомендовал пройти через их сайт.
Мое личное мнение заключается в том, что вам следует избегать использования JSP / ASP / PHP / etc страниц. Вместо этого выведите в API, похожий на SAX (только для вызова, а не для обработки). Таким образом, существует один слой, который должен создавать хорошо сформированный вывод.