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

var resizeTimer;
$( window ).resize(function() {
    if(resizeTimer){
        clearTimeout(resizeTimer);
    }
    resizeTimer = setTimeout(function() {
        //your code here
        resizeTimer = null;
        }, 200);
    });

Это работало на то, что я пытался сделать в хроме. Это не вызовет обратный вызов до 200 мс после последнего изменения размера.

67
задан BalusC 23 May 2015 в 05:19
поделиться

5 ответов

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

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

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


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

97
ответ дан 24 November 2019 в 14:35
поделиться

Если Вы хотите удостовериться, что Ваш $ оператор не страдает от взлома XSS, можно реализовать ServletContextListener и сделать некоторые проверки там.

полное решение в: http://pukkaone.github.io/2011/01/03/jsp-cross-site-scripting-elresolver.html

@WebListener
public class EscapeXmlELResolverListener implements ServletContextListener {
    private static final Logger LOG = LoggerFactory.getLogger(EscapeXmlELResolverListener.class);


    @Override
    public void contextInitialized(ServletContextEvent event) {
        LOG.info("EscapeXmlELResolverListener initialized ...");        
        JspFactory.getDefaultFactory()
                .getJspApplicationContext(event.getServletContext())
                .addELResolver(new EscapeXmlELResolver());

    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        LOG.info("EscapeXmlELResolverListener destroyed");
    }


    /**
     * {@link ELResolver} which escapes XML in String values.
     */
    public class EscapeXmlELResolver extends ELResolver {

        private ThreadLocal<Boolean> excludeMe = new ThreadLocal<Boolean>() {
            @Override
            protected Boolean initialValue() {
                return Boolean.FALSE;
            }
        };

        @Override
        public Object getValue(ELContext context, Object base, Object property) {

            try {
                    if (excludeMe.get()) {
                        return null;
                    }

                    // This resolver is in the original resolver chain. To prevent
                    // infinite recursion, set a flag to prevent this resolver from
                    // invoking the original resolver chain again when its turn in the
                    // chain comes around.
                    excludeMe.set(Boolean.TRUE);
                    Object value = context.getELResolver().getValue(
                            context, base, property);

                    if (value instanceof String) {
                        value = StringEscapeUtils.escapeHtml4((String) value);
                    }
                    return value;
            } finally {
                excludeMe.remove();
            }
        }

        @Override
        public Class<?> getCommonPropertyType(ELContext context, Object base) {
            return null;
        }

        @Override
        public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base){
            return null;
        }

        @Override
        public Class<?> getType(ELContext context, Object base, Object property) {
            return null;
        }

        @Override
        public boolean isReadOnly(ELContext context, Object base, Object property) {
            return true;
        }

        @Override
        public void setValue(ELContext context, Object base, Object property, Object value){
            throw new UnsupportedOperationException();
        }

    }

}

Снова: Это только охраняет $. Также см. другие ответы.

0
ответ дан 24 November 2019 в 14:35
поделиться

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

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

3
ответ дан 24 November 2019 в 14:35
поделиться

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

2
ответ дан 24 November 2019 в 14:35
поделиться

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

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

12
ответ дан 24 November 2019 в 14:35
поделиться
Другие вопросы по тегам:

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