Предотвращение XSS в веб-приложении JSP / Servlet - PullRequest
65 голосов
/ 17 апреля 2010

Как я могу предотвратить атаки XSS в веб-приложении JSP / Servlet?

Ответы [ 8 ]

93 голосов
/ 17 апреля 2010

XSS можно предотвратить в JSP с помощью тега JSTL <c:out> или fn:escapeXml() EL при (повторном) отображении user- контролируемый вход . Сюда входят параметры запроса, заголовки, файлы cookie, URL, тело и т. Д. Все, что вы извлекаете из объекта запроса. Кроме того, пользовательский ввод из предыдущих запросов, который хранится в базе данных, должен быть экранирован во время повторного отображения.

Например:

<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>

Это приведет к тому, что символы, которые могут искажать отображаемый HTML, такие как <, >, ", ' и &, превратятся в сущности HTML / XML , такие как &lt; , &gt;, &quot;, &apos; и &amp;.

Обратите внимание, что вам не нужно экранировать их в коде Java (сервлета), поскольку они там безвредны. Некоторые могут отказаться от них во время обработки запроса (как вы делаете в Servlet или Filter) вместо обработки response (как вы делаете в JSP), но в этом случае вы рискуете, что данные излишне экранируются (например, & становится &amp;amp; вместо &amp;, и в конечном итоге конечный пользователь увидит &amp; представление), или что данные, хранящиеся в БД, становятся непереносимыми (например, при экспорте данных в JSON, CSV, XLS, PDF и т. Д., Которые вообще не требуют экранирования HTML). Вы также потеряете социальный контроль, потому что вы больше не знаете, что на самом деле заполнил пользователь. Вы, как администратор сайта, действительно хотели бы знать, какие пользователи / IP-адреса пытаются выполнить XSS, чтобы вы могли легко отслеживать их и принять меры соответственно. Экранирование во время обработки запроса следует использовать только в качестве последнего средства, когда вам действительно необходимо в кратчайшие сроки исправить крушение поезда плохо разработанного устаревшего веб-приложения. Тем не менее, в конечном итоге вам следует переписать файлы JSP, чтобы они стали безопасными для XSS.

Если вы хотите снова отобразить ввод, управляемый пользователем, в виде HTML, в котором вы хотите разрешить только определенное подмножество тегов HTML, таких как <b>, <i>, <u> и т. Д., То вам необходимо санировать ввод белый список. Для этого вы можете использовать анализатор HTML, например Jsoup . Но гораздо лучше ввести дружественный для человека язык разметки, такой как Markdown (также используемый здесь при переполнении стека). Тогда вы можете использовать для этого анализатор Markdown, например CommonMark . Он также имеет встроенные возможности очистки HTML. См. Также Я ищу кодировщик Java HTML .

Единственной проблемой на стороне сервера в отношении баз данных является SQL-инъекция предотвращение. Вам нужно убедиться, что вы никогда не объединяете строки, контролируемые пользователем, прямо в запросе SQL или JPQL и что вы все время используете параметризованные запросы. В терминах JDBC это означает, что вы должны использовать PreparedStatement вместо Statement. В терминах JPA используйте Query.


Альтернативой может быть миграция из JSP / Servlet в инфраструктуру MVC Java EE JSF . Он имеет встроенную XSS (и CSRF!) Профилактику повсеместно. См. Также Предотвращение атак CSRF, XSS и SQL-инъекций в JSF .

12 голосов
/ 17 апреля 2010

Вопрос о том, как предотвратить xss, задавался несколько раз.Вы найдете много информации в StackOverflow.Кроме того, на веб-сайте OWASP есть листок с предупреждением XSS , с которым вам следует ознакомиться.

В библиотеках, которые нужно использовать, Библиотека ESAPI OWASP имеет формат java.Вы должны попробовать это.Кроме того, каждый используемый вами фреймворк имеет некоторую защиту от XSS.Опять же, на сайте OWASP есть информация о самых популярных фреймворках, поэтому я бы порекомендовал просмотреть их сайт.

11 голосов
/ 31 января 2011

Мне очень повезло с OWASP Anti-Samy и консультантом AspectJ по всем моим Spring Controllers, который блокирует доступ 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 из сообщения this stackoverflow

Я думаю, что это лучший подход, чем в частности, если вы делаете много javascript.

7 голосов
/ 30 октября 2012

Управление XSS требует нескольких проверок, данных со стороны клиента.

  1. Входные проверки (проверка формы) на стороне сервера. Есть несколько способов сделать это. Вы можете попробовать проверку bean-компонента JSR 303 ( средство проверки гибернации ) или Структура проверки ввода ESAPI . Хотя я сам не пробовал (пока), есть аннотация, которая проверяет безопасный html (@ SafeHtml) . На самом деле вы могли бы использовать валидатор Hibernate с Spring MVC для валидации бинов -> Ref
  2. Экранирование URL-запросов - Для всех ваших HTTP-запросов используйте какой-нибудь XSS-фильтр. Я использовал следующее для нашего веб-приложения, и оно заботится об очистке HTTP-запроса URL - http://www.servletsuite.com/servlets/xssflt.htm
  3. Экранирование данных / html , возвращаемых клиенту (см. Выше объяснение @BalusC).
3 голосов
/ 13 мая 2011

Нет простого, готового решения против XSS. OWASP ESAPI API имеет некоторую поддержку экранирования, которая очень полезна, и у них есть библиотеки тегов.

Мой подход состоял в том, чтобы в основном расширить теги stuts 2 следующими способами.

  1. Изменить тег s: property, чтобы он мог принимать дополнительные атрибуты, указывающие, какой тип экранирования требуется (escapeHtmlAttribute = "true" и т. Д.). Это включает в себя создание новых классов Property и PropertyTag. Класс Property использует OWASP ESAPI api для экранирования.
  2. Измените шаблоны свободных маркеров для использования новой версии свойства s: и установите экранирование.

Если вы не хотите изменять классы на шаге 1, другой подход заключается в импорте тегов ESAPI в шаблоны freemarker и при необходимости экранировании. Затем, если вам нужно использовать тег s: property в вашем JSP, оберните его тегом ESAPI.

Я написал более подробное объяснение здесь.

http://www.nutshellsoftware.org/software/securing-struts-2-using-esapi-part-1-securing-outputs/

Я согласен, что экранирование не является идеальным.

3 голосов
/ 17 апреля 2010

Я бы предложил регулярно проверять уязвимости с помощью автоматизированного инструмента и исправлять все, что он находит. Гораздо проще предложить библиотеку, которая поможет с определенной уязвимостью, чем для всех атак XSS в целом.

Skipfish - это инструмент с открытым исходным кодом от Google, который я исследовал: он находит довольно много вещей и, кажется, стоит использовать.

2 голосов
/ 11 июля 2012

Если вы хотите автоматически экранировать все переменные JSP без явного переноса каждой переменной, вы можете использовать распознаватель EL , как подробно описано здесь с полным исходным кодом и примером (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>
...

Если вы хотите принудительно экранировать по умолчанию в Spring, вы можете рассмотреть это также, но это не исключает выражения 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/

2 голосов
/ 19 апреля 2010

Мое личное мнение, что вам следует избегать использования страниц JSP / ASP / PHP / etc. Вместо этого выведите на API-интерфейс, аналогичный SAX (только для вызова, а не для обработки). Таким образом, существует один слой, который должен создавать правильно сформированный вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...