필자는 개발하던 중 CSRF토큰 발급을 Cookie(CsrfTokenRepository) 로 하고 있는 상황에서 CSRF쿠키를 받지 못하는 현상을 발견하였다.
번호인증의 경우 외부 서비스를 사용해야 하는데, 여기서 번호인증이 끝나고 콜백으로 클라이언트가 서버에 인증완료를 요청할때 쿠키를 전송하지 못하는 현상이 발생한 것이다. (쿠키를 전송하지 못하면 CSRF token을 재갱신한다)
쿠키가 전송되지 않아 발생할 수 있는 문제를 알아보도록 한다.
최근에 크롬에서 쿠키 정책 SameSite을 변경함에 따라 발생된 이슈이다.
https://www.chromium.org/updates/same-site
Cookie의 SameSite는 다른 외부도메인에서 요청이 올경우 쿠키를 전송에 대한 보안을 설정하는 정책이다.
최근에 "None"에서 Lax로 변경되었다.
Java SameSite 설정하기
java의 servlet-api 에서는 Cookie클래스에서 samesite에 대한 설정을 지원해주지 않는다.
여러가지 방법이 있겠지만 필자는 쿠키를 생성할때 생성된 Cookie를 가지고 다시 SameSite를 세팅해주는 방법으로
다음과 같이 사용하였다.
이때 SameSite를 설정할때에는 Secure도 같이 추가해줘야 한다.
해당 코드에서는 모든 SetCookie에 대해서 SameSite속성을 추가했지만 필요의 경우 해당 쿠키에 대해서만 SameSite를 추가하는 형태로 사용하면 된다.
(CookieCsrfTokenRepository를 사용하는 사람이 있다면 쿠키를 생성할때 saveToken의 로직을 수정해야 한다.)
※ 주의해야할것은 SameSite속성에 대한 값이다.
None으로 할경우 모든 외부 도메인에 대한 쿠키전송 보안을 허용해주는 것이기 때문에 주의해서 사용해야 한다.
※ 추가 주의
Seucure 속성을 주게 되면 Https 통신에서만 쿠키를 전송하게 된다.
로컬에서 Http로 테스트로 하게 될경우 Secure속성때문에 CSRF의 토큰이 제대로 발급되지 않는 현상이 발생할 수 있다.
어떤환경인지에 따라 적절한 쿠키를 발급해주는것이 중요할것으로 보인다.
댓글