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 토큰을 사용 시 비활성화