terça-feira, 11 de novembro de 2025

Configurando CSRF (Cross-Site Request Forgery) - Spring Security

        Nesse post vou falar sobre CSRF (Cross-Site Request Forgery - Falsificação de solicitação entre sites). O CSRF é um tipo de ataque onde um site malicioso tenta forçar o navegador de um usuário autenticado a enviar uma requisição indesejada para outro site (por exemplo, seu sistema), usando os cookies de sessão válidos daquele usuário.

        O Spring Security, por padrão, habilita a proteção contra CSRF para evitar isso — especialmente em aplicações web com sessões e formulários HTML (POST). Podemos desativar caso iremos usar aplicações com tokens JWT ou usar a configuração padrão. Abaixo temos os 2 exemplos para o Spring Boot a partir da versão 3.0: 


1. Desativando o CSRF (uso em APIs REST, JWT, stateless)

Esse é o que você mostrou:

httpSecurity
    .csrf(csrf -> csrf.disable())
    .authorizeHttpRequests(auth -> auth
        .requestMatchers("/api/**").permitAll()
        .anyRequest().authenticated()
    );
  • A aplicação não mantém sessão (SessionCreationPolicy.STATELESS costuma acompanhar isso).

  • Ideal para APIs REST com tokens JWT, pois o ataque CSRF depende de cookies, e aqui normalmente não há cookies.

Exemplo completo:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/auth/**").permitAll()
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
    return http.build();
}


2. Mantendo o CSRF Ativado (uso em apps web com formulários HTML)

        Aqui o CSRF é mantido ativo, e o Spring vai automaticamente gerar e validar tokens CSRF em formulários HTML.

httpSecurity
    .csrf(withDefaults()) // mantém o CSRF habilitado
    .authorizeHttpRequests(auth -> auth
        .requestMatchers("/login", "/register", "/css/**", "/js/**").permitAll()
        .anyRequest().authenticated()
    )
    .formLogin(withDefaults()) // usa login por formulário
    .logout(withDefaults());

        Nesse caso:

  • Todo formulário POST precisa incluir um campo hidden com o token CSRF.

  • O Spring automaticamente injeta esse token se você usar o Thymeleaf ou Spring Form Taglib, por exemplo:

    <form th:action="@{/login}" method="post">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
        <!-- campos de login -->
    </form>