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

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

Ответ 1

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-объекты, такие как &lt;, &gt;, &quot;, &apos; и &amp;.

Обратите внимание, что вам не нужно избегать их в коде Java (Servlet), поскольку они безвредны там. Некоторые могут отказаться от них во время обработки запроса (как в Servlet или Filter) вместо обработки ответа (как и в JSP), но таким образом вы можете рискнуть, что данные без необходимости получают двойное экранирование (например, & становится &amp;amp; вместо &amp;, и в конечном итоге enduser увидит &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-инъекций. Вы должны убедиться, что вы никогда не связываете строки с пользовательским контролем прямо в запросе SQL или JPQL и что вы используете параметризованные запросы полностью. В терминах JDBC это означает, что вместо Statement следует использовать PreparedStatement. В терминах JPA используйте Query.


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

Ответ 2

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

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

Ответ 3

Мне повезло с 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 из fooobar.com/questions/8723/...

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

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

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

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

Ответ 7

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

Ответ 8

Если вы хотите автоматически избегать переменных all 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>
...

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