CSRF(사용자 간 요청 위조: Cross Site Request Forgery )
。사용자 의도와는 무관하게 의도치않은 위조된HTTP Request를 전송하는 것
▶악성사이트가 중간에사용자 요청을위조해서대상 사이트에 전송하면서 공격하는 방법
。위조된 사이트내 잘못된HTTP 요청을 전달하는버튼을 구현하여브라우저의쿠키 정보내인증정보기반으로 해당 잘못된HTTP 요청을 전송
。CSRF의 경우 주로POST, PUT, PATCH , DELETE 요청에 대해서 주의해야한다.
CSRF원리
User가 웹사이트 로그인 시User Session가 생성되며, 해당User Session는Server에서 생성된Session Cookie를 사용하여 식별
User가 의도적이지 않게 해당 웹사이트에서 브라우저를 종료하거나로그아웃하지않고 다른 악성웹사이트로 이동 시 이전 웹사이트의Session Cookie에Access하여 탈취
- 공격자는 탈취한
Cookie를 악용해서 이전 웹사이트에서 원치않는Request를 강제로 실행.
CSRF Protection
。GETHttp Request Method를 제외한 상태를 변화 가능하게 하는POST, PUT, PATCH , DELETERequest로부터 Protection을 수행.
▶HTTP Request의X-CSRF-TOKEN에CSRF token이 포함되어야HTTP Request를 받아들임으로 위조요청을 방지.
。Spring Security에서 기본적으로 활성화 되도록 설정되어 Protection이 적용됨.
。STATELESS이거나non-BrowserClient를 위한 서비스인 경우,CSRF를disable설정하여CSRF Protection을 비활성화해도 된다.
▶ 따로 사용자에게세션또는토큰을 부여하지 않으므로.
CSRF Protection해결 방법
CSRF Token:
。CSRF공격을 방지하기 위해 사용되는TOKEN Pair
▶ 한토큰은서버 세션 인메모리 DB에 저장하고, 나머지토큰은HTTP Response Header에 저장
。Spring Security는CSRF를 가진요청만통신을 허용하도록 설정되어CSRF 토큰이 없으면 무조건 차단
▶ 반드시HTTP 요청의Header:X-CSRF 토큰이 포함되어야함.
。Server에서Client의 이전HTTP Request에서Session과 연결된CSRF Token을 발급 및Client는 매번Http Request를 전송할때마다 이전HTTP Request에서 발급된 고유한CSRF Token을X-CSRF-TOKENHeader로 포함하여 함께 전송하는 방식.
▶Thymeleaf를 통해 Web Application을 build 시Spring Security는 자동으로 모든Form에CSRF Token을 생성하여 추가된다.
。CSRF Token획득 방법 :
Controller Method의 매개변수의HttpServletRequestinstance를 통해 해당REST API호출시의HTTP Request에서 보통form에서type=hidden으로 숨겨진<input>field의name="_csrf"를 참조하여CSRF-TOKEN을CsrfToken으로 캐스팅하여 반환하는Controller Method생성
X-CSRF-TOKEN:CSRF Token을HTTP Request의headers에 포함하는 역할을 수행.
CSRF 비활성화:
。 Client에서JWT Token을 사용하여REST API를 호출하는Session을 사용하지않는STATELESS의 경우에만CSRF Protection비활성화를 수행
。SecurityFilterChain을 Configuration 후 반환하는@Bean Method에서HttpSecurity객체를 이용하여httpsecurity객체.csrf(csrf->csrf.disable());선언.
SameSite Cookie
。Client가Cookie를HTTP Request와 함께 전송할 수 있는 범위를 제한하는 보안속성
▶ 타 사이트에서 HTTP Request 시Cookie가 전송되지 않도록 제한함으로써CSRF공격 방지용도로 활용.
。Spring의application.yml에서 다음을 설정.server.servlet.session.cookie.same-site=strict
same-site=strict:
。오직 동일한 사이트에서만 HTTP Request에Cookie를 포함하여 전송.
▶ 가장 강력한 보안으로 사이트 간 모든HTTP Request에는Cookie를 미포함.
same-site=lax:
。외부 사이트에서 HTTP Request를 전송 시GET Request Method에 대해서만Cookie를 포함.
▶POST,PATCH,DELETE등의Request Method또는AJAX의HTTP Request에는Cookie가 포함되지 않음.
。CSRF공격을 방지하면서도 정상적인 링크 이동이 가능하도록 구축 시 사용.
same-site=none:
。모든HTTP Request에Cookie가 항상 포함되도록 설정.
▶CSRF공격에 매우 취약하므로,CSRF Token을 활용하여 추가적인 보안조치를 수행해야한다.
CSRF관련 설정
。SecurityFilterChain관련@Configuration 클래스에서 설정을 수행
httpsecurity객체.csrf(콜백함수)
。HttpRequest에 대한CSRF Protection을 설정하는 method.
▶Spring Security는CSRF Protection이 기본적으로 활성화되어있으므로, 해당 method를 이용해 비활성화 설정이 가능.
。람다식의 매개변수로서CSRFinstance가 input.http.csrf(csrf->csrf.disable());。
HttpSecurity객체의Filter chain에서CSRF Protection을 비활성화하도록 설정
▶ 다음 코드는 다음처럼메서드참조로 축약이 가능.csrf(AbstractHttpConfigurer::disable)。
Session이 존재하지 않는 경우는비활성화해도 되지만,Session이 존재하는 경우, 반드시CSRF protection을 활성화해야한다.
▶Spring Security에서는 default로CSRF protection활성화로 설정되어있으므로JWT 토큰을 사용 시 비활성화