개요
스프링 기반 프로젝트를 진행하면서 여러분들은 다음과 같은 코드를 많이 접해봤을 것입니다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
Java
복사
바로 csrf 보안을 비활성화 하는 코드입니다.
이번 포스팅에서는 왜 많은 프로젝트에서 csrf 보안을 비활성화 하는지 그 이유에 대해 알아보겠습니다!
1. csrf란?
위키백과는 csrf를 다음과 같이 정의하고 있습니다.
예를 들어 볼까요?
사용자는 은행 업무를 위해 은행 웹 사이트에 로그인 했습니다. 로그인 후, 사용자의 브라우저는 인증 정보를 저장합니다.
사용자는 해커가 만든 악성 웹 사이트에 접속합니다. 해당 웹 사이트는 사용자 모르게 특정 요청을 보내는 코드를 포함하고 있습니다.
악성 코드는 사용자의 계좌에서 해커의 계좌로 송금을 요청하는 코드이며, 사용자의 브라우저에 저장된 인증 정보와 함께 송금 요청이 전송됩니다.
은행은 이를 정상적인 요청으로 인식하고, 해커의 계좌로 송금을 진행합니다.
csrf는 공격을 방어하기 위해 다음과 같은 방법을 사용합니다.
•
사용자의 세션에 고유한 CSRF 토큰을 생성하고, 모든 폼 제출 또는 상태를 변경하는 요청에 이 토큰을 포함시킵니다. 서버는 요청을 받을 때마다 이 토큰을 검증하여 요청의 유효성을 판단합니다.
•
쿠키에 SameSite 속성을 설정하여, 쿠키가 동일한 사이트의 요청에서만 전송되도록 할 수 있습니다.
2. 그렇다면 왜 csrf를 비활성화 하는가?
왜냐하면 대부분의 서버들이 REST API 기반의 서버 이기 때문입니다. REST API 기반의 서버는 stateless의 특성을 가지며, 이로 인해 csrf 공격으로 부터 비교적 안전합니다.
대신 클라이언트는 각 요청에 필요한 모든 정보를 인증 토큰을 포함하여 서버에 전송합니다.
REST API에서는 일반적으로 Access Token(접근 토큰)과 Refresh Token(갱신 토큰)을 사용하여 사용자 인증을 관리합니다. 이 토큰들은 클라이언트 측에서 관리되며, 서버는 각 요청이 유효한 토큰을 포함하고 있는지를 검증합니다.
3. 결론
따라서 REST API는 상태를 저장하지 않는 방식을 취하기 때문에, 세션 기반 인증이 필요하지 않으며, 요청에 토큰을 포함시키는 방식으로 공격에 방어하기 때문에 csrf를 비활성화 해도 무방합니다!