CSRF

CSRF란?

CSRF는 Cross-Site Request Forgery의 약어로, "사이트간 요청 위조"를 의미한다. 공격자가 사용자가 로그인한 웹사이트를 통해 사용자가 모르는 상황에서 원치 않는 동작을 수행하게 하는 보안 취약점이다. 

위 이미지와 같이 공격을 방지하기 위해 웹 개발자들은 요청을 보낼 때 추가적인 보안 검증 절차를 구현하고, 사용자에게 요청의 적절성을 확인하도록 요청하는 등의 대응 방안을 마련해야 한다. 

 


 

CsrfFilter

CsrfFilter란?

CsrfFilter는 웹 어플리케이션에서 CSRF(Cross-Site Request Forgery) 공격을 방지하기 위한 필터다. 

Spring Security에서 제공하는 CsrfFilter는, HTTP 요청에 대해 CSRF 토큰을 생성하고, 이 토큰을 쿠키에 저장한다. 그리고 나서, 모든 POST, PUT, DELETE 요청에 대해 CSRF 토큰이 함께 전송되어야 하는지를 검증한다. 만약 요청에 CSRF 토큰이 없다면, 해당 요청을 차단한다. 

 

사용법

Spring Security를 사용하는 웹 어플리케이션에서는, CsrfFilter를 설정하여 간단하게 CSRF 공격으로부터 보호할 수 있습니다. http.csrf() 로 설정하면 활성화되지만 기본 활성화되어 있으므로 따로 설정할 필요는 없다. 기능이 활성화되면 아래와 같은 역활을 수행한다.

  • 모든 요청에 랜덤하게 생성된 토큰을 HTTP 파라미터로 요구
  • 요청 시 전달되는 토큰 값과 서버에 저장된 실제 값과 비교한 후 만약 일치하지 않으면 요청은 실패한다

 

테스트

아래와 같이  http.csrf() 를 설정해주지 않은상태에서 테스트를 시작한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
			.anyRequest()
			.permitAll(); 

		http
			.formLogin();
		
		return http.build();
	}

}

 

 

포스트맨을 사용하여 POST로 Body나 Header에 토큰값을 담지 않고 요청을 보낸다.

 

CsrfFilter.java의 doFilterInternal() 에서 (1) 은 서버에 저장된 토큰이고 (2) 는 클라이언트에서 주는 토큰인데 토큰을 주지 않았기에 null로 확인이된다.

 

 

토큰 값을 헤더 키 :  X-CSRF-TOKEN  값 : 355391cd-13a2-4ddd-9c96-b49fb21f8a23 를 넣어 다시 요청을 보낸다.

 

토큰과 함께 요청를 했으니 actualToken에 토큰값이 확인이 가능하다.

 

비활성화는 아래 방법으로 가능하다.

http.csrf().disable();

 

복사했습니다!