Spring/security

[시큐리티] CSRF

라임온조 2023. 3. 27. 18:15

1. 개념

사용자 A, A가 사용하는 서비스 B, 공격자 C가 있다고 하자. A는 B에 로그인을 한다. 로그인 된 상태로 A는 C가 보낸 이상한 링크를 통해 어떤 사이트에 접속한다. 이 사이트에는 B에 광고성으로 글을 올릴 수 있는 위조된 코드가 들어있다. A가 B에 로그인을 한 상태로 위조된 코드가 있는 사이트에 들어갔는데 만약 B가 요청이면 무조건 승낙을 하는 보안 정책을 가지고 있다면 B에는 위조된 요청에 의해 A의 계정으로 광고성 글이 작성된다.

이처럼 위조된 요청으로 서버에 어떤 작업을 시킬 수 있는 것이 CSRF이다.

 

2. 보호 방법

1) csrf 토큰

get요청이 들어왔을 때 서버가 고유한 csrf 토큰을 생성해서 클라이언트에게 보내고, 클라이언트는 이후 post, put, delete 등의 수행을 할 때 아까 받은 고유한 csrf 토큰을 헤더에 넣어서 보낸다. 서버는 요청이 왔을 때 get 요청이 왔을 때 보낸 토큰과 일치한지 확인해서 일치하면 올바른 요청이라고 본다.

 

2) CsrfFilter

클라이언트의 요청이 들어왔을 때, 요청을 가로챈다. 이후, GET, HEAD, TRACE, OPTIONS의 http 방식 요청은 모두 허용하고 다른 모든 요청에는 csrf 토큰이 포함된 헤더가 있는지 확인을 한다. 만약 헤더에 csrf 토큰이 없거나 올바른 토큰이 아니라고 판명나면 요청이 거부되고 http 상태 코드 403을 리턴한다. 헤더에 올바른 csrf 토큰이 있으면 이를 http 요청의 _csrf 특성에 저장해놓는다.

 

3) CsrfTokenRepository

CsrfFilter는 CsrfTokenRepository를 이용해 CSRF 토큰을 관리한다. CsrfTokenRepository는 토큰을 HTTP 세션에 저장하고, 랜덤 UUID로 토큰을 생성한다.

 

필터 체인의 한 부분에 CsrfFilter가 있다. 이 필터는 CsrfFilter에 설명해놓은 것과 같은 동작을 수행한다. 이 필터 뒤에 csrfFilter에서 생성한 csrf 토큰을 얻어 무언가를 하는 필터를 추가할 수도 있다.

 

3. CSRF 보호 맞춤 구성

1) 특정 경로에만 csrf 보호 적용

ignoringAntMatchers(String paths)

csrf 보호 메커니즘에서 제외할 경로를 인자로 넘겨줌

http.csrf(c -> {
    c.ignoringAntMatchers("/ciao");
});

ignoringRequestMatchers()

일반 MVC 식과 정규식으로 제외 규칙을 적용할 수 있음

http.csrf(c -> {
    

    HandlerMappingIntrospector i = new HandlerMappingIntrospector();
    MvcRequestMatcher r = new MvcRequestMatcher(i, "/ciao");
    c.ignoringRequestMatchers(r);

    
});
http.csrf(c -> {


    String pattern = ".*[0-9].*";
    String httpMethod = HttpMethod.POST.name();
    RegexRequestMatcher r = new RegexRequestMatcher(pattern, httpMethod);
    c.ignoringRequestMatchers(r);


});

2) csrf 토큰을 http 세션이 아닌 데이터베이스에 저장

CsrfToken

  • csrf 토큰 자체를 기술
  • csrf 토큰의 값을 포함하는 헤더 이름, 토큰 값을 저장하는 변수 이름, 토큰의 값이 필요함
  • DefaultCsrfToken을 사용해서 구현 가능

CsrfTokenRepository

  • csrf 토큰을 관리(생성, 저장 등)

방법

  • 데이터베이스에 저장할 token 테이블과 엔티티 생성
  • 데이터베이스에 있는 token 테이블에 접근할 jpaRepository 생성
  • csrfToken을 관리할 CustomCsrfTokenRepository 재정의
  • Configuration에서 설정

자세한 코드는 깃허브 참조

 

'Spring > security' 카테고리의 다른 글

[시큐리티] 토큰  (0) 2023.03.29
[시큐리티] CORS  (0) 2023.03.28
[시큐리티] 필터  (0) 2023.03.23
[시큐리티] 권한과 역할제어  (0) 2023.03.21
[시큐리티] SecurityContext  (0) 2023.03.16