CSRF и Spring Security
CSRF заставляет браузер авторизованного пользователя отправить изменяющий запрос на чужой сайт. Атака работает, когда браузер автоматически добавляет credential: session cookie, Basic auth или client certificate.
пользователь вошёл в bank.example
↓ cookie хранится в браузере
пользователь открыл evil.example
↓ форма отправляет POST на bank.example
браузер сам добавляет cookieSame-origin policy мешает прочитать ответ, но не всегда мешает отправить запрос.
Механизм token
Сервер выдаёт непредсказуемый CSRF token, связанный с пользовательским контекстом. Клиент возвращает его в параметре формы или заголовке. Чужой сайт не знает token, поэтому проверка отклоняет запрос.
В современной servlet-конфигурации Spring Security CSRF-защита включена по умолчанию:
@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.csrf(Customizer.withDefaults());
return http.build();
}HTML form должна отправить token. Интеграция Spring MVC/template engine может добавить hidden field; SPA обычно получает token выбранным repository-механизмом и отправляет заголовок.
Когда отключение обосновано
Для API, где браузер не использует автоматически прикрепляемые credentials, а клиент вручную передаёт bearer token в Authorization, классический CSRF-риск обычно отсутствует. Но это надо доказать для всех endpoints. Если тот же API принимает cookie или Basic auth, защита снова нужна.
http.csrf(csrf -> csrf.disable()); // только после зафиксированной threat modelОтключение CSRF не защищает от XSS, кражи токена, CORS-ошибок или неверной авторизации. SameSite cookie — дополнительный слой, а не универсальная замена token.
Ошибки
- отключить CSRF, потому что «это REST»;
- применять token только к одному state-changing методу;
- разрешить
GETменять состояние; - логировать token;
- выставить cookie token доступным JavaScript без оценки XSS.
Проверка
Тест должен подтвердить обе стороны: запрос без token отклоняется, с корректным token проходит. В spring-security-test для MockMvc используется request post-processor csrf().
На собеседовании
Почему cookie-аутентификация уязвима? Браузер автоматически прикладывает cookie к запросу на целевой origin.
CSRF token аутентифицирует пользователя? Нет, он подтверждает, что запрос сформирован в допустимом контексте.
Нужно ли защищать GET? GET не должен менять состояние; обычно token проверяют для unsafe HTTP methods.
Когда stateless API может отключить CSRF? Когда ни один поддерживаемый credential не прикладывается браузером автоматически и это закреплено архитектурой.
Связано: Безопасность приложения Spring Security, Spring WEB, HTTP протокол.