Предотвращение подделки межсайтовых запросов в приложении Spring WebFlow - PullRequest
6 голосов
/ 03 мая 2010

Я ищу (надеюсь, простой) способ добавления CSRF защиты к сборке приложения на Spring WebFlow 2.

Подход, который хорошо переносится на Spring WebFlow 3 (когдаосвобожден) является предпочтительным.

Ответы [ 2 ]

4 голосов
/ 04 мая 2010

Самый простой способ запретить CSRF это проверить реферер request.getHeader("referer");, чтобы убедиться, что запрос поступает из того же домена. Этот метод описан в Шпаргалке по профилактике CSRF *1003*.

Обычно эта система защиты CSRF используется на встроенном сетевом оборудовании с ограниченными требованиями к памяти. Motorola использует этот метод на большинстве своего оборудования. Это не самая безопасная защита CSRF, защита на основе токенов лучше, но обе системы все еще можно обойти с помощью xss. Самая большая проблема с защитой CSRF на основе токенов заключается в том, что для возврата и исправления каждого запроса требуется много времени, и вы, вероятно, пропустите несколько запросов.

Безопасный способ реализовать это - проверять реферер по всем входящим запросам POST и использовать POST для чувствительных функций, таких как изменение паролей, добавление учетных записей пользователей, выполнение кода, внесение изменений в конфигурацию. GET следует использовать только для навигации или поиска, в основном GET безопасен для всего, что не вызывает изменения состояния.

Убедитесь, что вы тестировали свой сайт с помощью xss сканера .

2 голосов
/ 10 ноября 2011

OWASP имеет хорошее руководство по предотвращению CSRF-атак здесь :

Проверка заголовка Referer, безусловно, самая простая и хорошая идея, по крайней мере, регистрировать случаи, когда Referer является сторонним или пустым. Однако есть несколько недостатков, которые делают использование только одного реферера ненадежным:

  • Корпоративные брандмауэры могут лишить заголовок реферера по соображениям конфиденциальности
  • При переходе с HTTPS на HTTP реферер не отправляется
  • В атаках CFRF обычно трудно «подделать» реферера, но это может быть выполнено с использованием мета-тегов обновления.

К счастью, WebFlow позволяет легко реализовать собственный уникальный CSRF-фильтр токенов для каждого потока (вам может не понадобиться изменять какие-либо представления / формы)!

Сначала используйте FlowExectionListener для создания нового случайного токена при каждом запуске потока и сохранения его в flowScope. Затем всякий раз, когда событие сигнализируется, убедитесь, что переданный токен (представленный в качестве параметра в запросе) равен значению, сохраненному в flowScope.

Затем настройте пользовательский FlowUrlHandler, который добавляет параметр «_token» к сгенерированным URL-адресам, поэтому, если вы использовали $ {flowExecutionUrl} для ссылки на свои потоки, токен будет добавляться всякий раз, когда вы автоматически POST / GET возвращаетесь к своему потоку. Чтобы получить токен из flowScope из FlowUrlHandler, мне пришлось прибегнуть к использованию RequestContextHolder

 private String retrieveToken() {
    RequestContext requestContext = RequestContextHolder.getRequestContext();
    if (requestContext == null) {
        return null;
    }
    return (String) requestContext.getFlowScope().get(CsrfTokenFlowListener.TOKEN_NAME);
}
...

Этот метод будет включать токен CSRF всякий раз, когда вы выводите $ {flowExecutionUrl} - как для GET, так и для POST, и если вы используете post-redirect-get, вы можете убедиться, что маркер CSRF не появится в URL бар.

Я бы предостерег от проверки только токенов CSRF на POST:

WebFlow и многие другие веб-фреймворки не различают GET и POST - по умолчанию вы, как правило, можете использовать GET, чтобы делать все, что вы делаете с POST, если вы сами не проверите метод запроса (что в любом случае было бы хорошей идеей) ). Так что злоумышленник, желающий обойти ваш CSRF-фильтр, просто сделает GET вместо POST.

Редактировать: Один недостаток, который следует учитывать при включении токенов CSRF в $ {flowExecutionUrl}, заключается в том, что токен CSRF, скорее всего, всегда будет отправляться как часть URL-адреса запроса (поскольку он будет частью атрибут «действия» HTML-формы), а не в теле POST. Включение конфиденциальной информации в URL-адрес запроса не очень хорошо, так как оно более вероятно будет зарегистрировано в журналах сервера / интернет-провайдера. Альтернативой является добавление скрытого ввода в каждую форму, содержащую токен CSRF, и принудительное использование его только для запросов POST.

...