Предотвращение XSS в веб-приложении JSP / Servlet

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

8 ответов


XSS можно предотвратить в JSP с помощью тегов JSTL <c:out> тег или fn:escapeXml() функция EL, когда (re)отображение пользователь-управляемый вход. Это включает параметры запроса, заголовки, куки, 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 (сервлета), так как они безвредны там. Некоторые могут выбрать, чтобы избежать их в запрос обработка (как в сервлете или фильтре) вместо ответ обработка (как вы делаете в JSP), но таким образом вы можете рисковать, что данные излишне получить двойной побег (например,& становится &amp;amp; вместо &amp; и в конечном итоге пользователь будет видеть &amp; представляется), или что данные, хранящиеся в БД, становятся непортящимися (например, при экспорте данных в JSON, CSV, XLS, PDF и т. д., Что не требует HTML-экранирования вообще). Вы также потеряете социальный контроль, потому что вы больше не знаете, что на самом деле имеет пользователь заполненный. Вы как администратор сайта действительно хотите знать, какие пользователи / IPs пытаются выполнить XSS, чтобы вы могли легко отслеживать их и предпринимать соответствующие действия. Побег во время обработки запроса должен использоваться только как последнее средство, когда вам действительно нужно исправить крушение поезда плохо разработанного устаревшего веб-приложения в кратчайшие сроки. Тем не менее, вы должны в конечном итоге переписать свои файлы JSP, чтобы стать XSS-safe.

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

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


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


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

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


Мне очень повезло с 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

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


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

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

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

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


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

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

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

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

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

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

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


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


Если вы хотите автоматически избежать все переменные JSP без необходимости явно обертывать каждую переменную, вы можете использовать El resolver как подробно описано здесь с полным источником и примером (JSP 2.0 или новее), и обсуждается более подробно здесь:

например, используя вышеупомянутый El resolver, ваш код JSP останется таким, но каждая переменная будет автоматически экранирована resolver

...
<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/