Tomcat 7 и фильтр CSRF

Я пытаюсь добавить защиту CSRF в веб-приложение Java. У меня настроен файл web.xml с фильтром CSRF и сопоставлением фильтров с сервлетами. Однако я не уверен, как сделать следующую часть. в документации говорится, что все URL-адреса, возвращаемые клиенту, кодируются с помощью вызова HttpServletResponse#encodeRedirectURL(String) или HttpServletResponse#encodeURL(String). Они также говорят, что вы можете попробовать: Или можно передать одноразовый номер в качестве параметра запроса с именем org. apache.catalina.filters.CSRF_NONCE — значение константы org.apache.catalina.filters.Constants.CSRF_NONCE_REQUEST_PARAM.

ОБНОВЛЕНИЕ Я все еще не могу получить ошибку 403 "запрещено". у кого-нибудь есть предложения? Вот настройка web.xml:

<filter>
    <filter-name>CSRF</filter-name>
    <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
    <init-param>
      <param-name>entryPoints</param-name>
      <param-value>/html,/html/</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CSRF</filter-name>
    <servlet-name>exampleservlet</servlet-name>
  </filter-mapping>

Вот код страницы JSP

<FORM METHOD="POST"  ACTION="<%=response.encodeURL("/exampleservlet")%>">
        <INPUT TYPE="HIDDEN" NAME="org.apache.catalina.filters.CSRF_NONCE" VALUE="<%=session.getAttribute("org.apache.catalina.filters.CSRF_NONCE")%>">
        <INPUT TYPE="HIDDEN" NAME="id" VALUE="0">

Что я делаю не так?


person user1173894    schedule 24.07.2014    source источник
comment
У нас тоже такая же проблема. Кто-нибудь получил решение?   -  person Piyush Gupta    schedule 20.09.2017


Ответы (1)


Я думаю, что сейчас это не более важно, поскольку вопрос поднимался много лет назад, но я иногда посещаю его, чтобы получить некоторые советы по использованию org.apache.catalina.filters.CsrfPreventionFilter. Как описано в документе с официального сайта tomcat CSRF_Prevention_Filter, предполагается, что этот CsrfPreventionFilter сопоставляется с "/*" и использует init-param с именем "entryPoints" для хранения URL-адресов для

предоставить способ вернуться к защищенному приложению после выхода из него

Я постараюсь объяснить работу, проделанную CsrfPreventionFilter, простым языком:

  1. Сначала, когда клиент получает доступ к приложению, запрошенный URL-адрес должен быть сопоставлен фильтром и соответствовать одному из entryPoints. Чтобы CsrfPreventionFilter мог генерировать новый одноразовый номер и сохранять в сеансе и обертывать ответ, переопределяя HttpServletResponse#encodeRedirectURL(String) и HttpServletResponse#encodeURL(String), при этом не блокируя запрос (возвращая 403).
  2. URL-адреса на странице должны быть закодированы HttpServletResponse#encodeRedirectURL(String) or HttpServletResponse#encodeURL(String), как вы сделали в действии формы. На самом деле «кодировка» заключается в добавлении имени параметра запроса «org.apache.catalina.filters.CSRF_NONCE» со значением одноразового номера, сгенерированного фильтром на первом этапе.
  3. Когда клиент получает доступ к URL-адресам на странице, которые закодированы, CsrfPreventionFilter будет проверять, действительны ли запросы - соответствует ли одноразовый номер одному из тех, которые хранятся в текущем сеансе (используя LRUCache с размером по умолчанию 5, можно установить через init- параметр nonceCacheSize).

Таким образом, если объявленный вами сервлет exampleservlet также не сопоставлен с "/*" или "/html,/html/", а /html может привести к странице, содержащей форму, ваш код не будет работать.

Поскольку ответ, который вы используете в

<FORM METHOD="POST" ACTION="<%=response.encodeURL("/exampleservlet")%>">

не обернут CsrfPreventionFilter и не будет волшебства для добавления одноразового номера.

Ни

<INPUT TYPE="HIDDEN" NAME="org.apache.catalina.filters.CSRF_NONCE" VALUE="<%=session.getAttribute("org.apache.catalina.filters.CSRF_NONCE")%>">

будет успешным, потому что атрибут сеанса "org.apache.catalina.filters.CSRF_NONCE" никогда не устанавливался фильтром. Даже если он есть, он содержит экземпляр LRUCache, но не строку одноразового номера.

person KenZZ    schedule 17.10.2017