Вопрос по servlets, jsp, xss, security, java – Предотвращение XSS в веб-приложении JSP / Servlet

63

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

Великий пост о том, как предотвратить XSS-атаки в различных ситуациях, размещен там:stackoverflow.com/questions/19824338/... user1459144

Ваш Ответ

8   ответов
2

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

91

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), поскольку они там безвредны. Некоторые могут избежать их во времязапрос обработка (как вы делаете в сервлете или фильтре) вместоответ обработки (как вы делаете в 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.

@BalusC: Привет, Бал, по твоему предложению я удалил 4 проблемы XSS в своем приложении, большое спасибо за полезное решение. Здесь мне снова нужно ваше предложение, когда я отображаю объект dom, используя jstl espression<div><c:out value="${htmlContent}" escapeXml="false" /></div> ВотhtmlContentценность что-то вроде<span><h1>Hi</h1></span> (это значение из базы данных) теперь, если я удалюescapeXml="false" отc:out затем его отображает, как он есть на странице, то если сохранитьescapeXml="false" он правильно анализирует объект dom, но когда мой htmlContent имеет некоторый код скрипта, тогда возникает проблема с xss. Venki
@BalusC: пожалуйста, расширяться. Guido Celada
@Venki: Просто прочитайте четвертый абзац ответа, в котором рассказывается о работе с HTML, контролируемым пользователем. BalusC
@ Чад: это не правда. Это только тот случай, когда вы объединяете строки, контролируемые пользователем, прямо в запросе SQL / HQL / JPQL следующим образом"SELECT ... WHERE SOMEVAL = " + someval вместо использования параметризованных запросов, как вы показали. Ни один ORM не может защитить от подобных ошибок разработчиков. BalusC
2

Если вы хотите автоматически сбежатьвсе Переменные 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/

7

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

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

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

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

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

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

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

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

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

12

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

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

Шпаргалки OWASP перенесены на GitHub. Вот ссылка на Шпаргалку по профилактике XSSgithub.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/... peater
3

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

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

Профилактика лучше диагностики (например, skipfish) с последующим быстрым исправлением. Sripathi Krishnan
Я не согласен. Профилактика без диагноза - это просто догма. Запустите диагностику как часть цикла CI, чтобы избежать проблемы «быстрого устранения». Sean Reilly
11

Мне очень повезло с 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 отэтот стековый пост

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

Обычной практикой является экранирование HTML любых контролируемых пользователем данных во время повторного отображения, а не во время обработки отправленных данных в сервлете или во время хранения в БД. Если вы удалите его из HTML во время обработки отправленных данных и / или хранения в БД, то все это распространяется по бизнес-коду и / или в базе данных. Это только проблема технического обслуживания, и вы рискуете получить двойной выход или даже больше, если будете делать это в разных местах. Бизнес-код и БД, в свою очередь, не чувствительны к XSS. Только вид есть. Вы должны тогда избежать этого только там, в поле зрения. Shubham Maheshwari
Да, я, возможно, должен сделать мой случай использования более ясным. Я работаю в основном над управлением контентом (редактирование HTML). Adam Gent
как вы и я оба упомянули, «нормальная практика» состоит в том, чтобы избежать демонстрации. То, что вы упомянули в вышеприведенном комментарии, является более конкретным вариантом использования и, следовательно, может потребовать определенных решений. Shubham Maheshwari
И да и нет. Хотя общая практика состоит в том, чтобы избежать демонстрации, есть много причин, по которым вы можете захотеть санировать при записи. В некоторых случаях вы хотите, чтобы ваши пользователи вводили подмножество HTML, и хотя вы могли бы санировать на дисплее, это на самом деле довольно медленно и даже вводит пользователей в заблуждение. Во-вторых, если вы делитесь данными со сторонними сервисами, такими как внешние API, эти сервисы могут выполнять или не выполнять надлежащую санитарную обработку. Adam Gent

Похожие вопросы