본문 바로가기

프로젝트/중고 거래 플랫폼

CSRF의 정의와 프로젝트에서의 방어했던 방법

목차

    CSRF (Cross-Site Request Forgery)

    CSRF는 희생자가 이미 인증된 상태에서 공격자가 의도한 행위를 서버에 요청하게 만드는 공격 유형이다.

    이 공격은 토큰이나 쿠키를 직접 탈취하는 것이 아니라, 희생자의 브라우저를 이용하여 공격자가 원하는 요청을 서버에 보내게 만드는 방식으로 이루어진다.

     

    https://tibetsandfox.tistory.com/11

     

    CSRF(Cross Site Request Forgery)란?

    CSRF란? CSRF는 Cross Site Request Forgery(사이트 간 요청 위조)의 줄임말로 웹 취약점 중 하나입니다. 공격자가 희생자의 권한을 도용하여 특정 웹 사이트의 기능을 실행하게 할 수 있으며 이는 희생자

    tibetsandfox.tistory.com

     

    발생 과정

     

    1. 희생자가 위조 요청을 보낼 사이트에 로그인 되어있는 상태로 피싱 사이트에 접속하게 된다.
    공격자는 피싱 사이트 접속 유도를 위해 피싱 메일, 팝업 광고를 띄우는 등의 행동을 한다.

    2. 희생자가 피싱 사이트에 접속하면 피싱 사이트에서 희생자로 가장하여 요청을 위조해 전송한다.
    희생자가 이미 인증된 상태(예: 로그인 상태)에서 희생자의 브라우저를 이용해 의도하지 않은 요청을 서버에 보내게 하는 것이다.


    3. 위조 요청을 받은 사이트는 해당 요청에 대한 응답을 하게 되고 이로 인해 희생자가 의도하지 않은 행동이 실행된다.

     

    방어 방법

     

    1. JWT나 Stateless Session 사용

    JWT를 사용하면 서버는 상태를 유지할 필요가 없으므로, CSRF 공격의 위험이 감소한다.

    JWT는 사용자의 상태를 서버에 저장하지 않고, 토큰 자체에 인증 정보를 포함하기 때문이다.

     

    궁금증과 해답 : 어떻게 JWT로 방어할 수 있지?

    근데 어떻게 JWT로 방어할 수 있지? 희생자가 의도치 않은 행위를 하게 되면 어차피 JWT도 알아서 보내지는게 아닌가? 라는 생각이 들었다. 

     

    해답

    CSRF 공격은 브라우저가 자동으로 쿠키를 포함하여 요청을 보내는 성질을 이용한다.

    그러나 JWT가 헤더에 포함되어 있을 경우, 브라우저는 자동으로 이를 요청에 포함시키지 않는다.

    클라이언트에서 직접 헤더에 담아야 하니 당연한 이야기이다.

     

    토큰 기반 인증의 취약점?

    하지만 해답과 달리, JWT를 쿠키에 저장하는 경우(특히 HttpOnly가 아닌 경우) CSRF 공격의 위험이 여전히 존재한다.

    쿠키의 경우는 웹 사이트의 요청에 자동적으로 담겨 전송되기 때문이다.

     

    내 이번 프로젝트의 경우 Refresh-Token에 HttpOnly속성을 달았지만, 아래와 같은 적절한 CSRF 보호 메커니즘을 추가로 적용해야 했다.

    CSRF 토큰, SameSite 쿠키 속성 사용

    Spring Security는 CSRF 보호를 위해 CSRF 토큰을 제공한다.

    이 방식은 서버가 각 세션에 대해 고유한 토큰을 생성하고, 클라이언트는 요청과 함께 이 토큰을 제출해야 한다.

    이번 프로젝트에서는 세션 스토리지를 고민하여 사용하지 않았다.

     

    대신 쿠키에 SameSite 속성을 추가로 설정하여, 쿠키가 다른 사이트의 요청에 따라 전송되는 것을 제한하였다.

    기본적인 CSRF 방지는 시행했지만, 추가적으로 CSRF 토큰을 사용하여 이중으로 보완하면 좋을 것 같다는 아쉬움이 남는다. 다음 프로젝트에는 이를 적용할 것이다.