2020년 2월 4일 릴리즈된 구글 크롬(Google Chrome) 80버전부터 새로운 쿠키 정책이 적용 되어 Cookie의 SameSite 속성의 기본값이 "None"에서 "Lax"로 변경되었습니다.
SameSite 를 None 으로 설정할 경우 모든 도메인에서 쿠키를 전송하고 사용할 수 있지만 사용자가 사이트 간 요청 위조(CSRF - Cross-site request forgery) 및 의도하지 않은 정보 유출에 취약해질 가능성이 있습니다. 이러한 취약점을 방지하기 위해 지금까지는 별도의 SameSite 속성 명시 없이 쿠키를 생성했을 때 "SameSite=None" 으로 설정한 것과 동일하게 동작 했지만 Chrome80 버전 이후에는 SameSite 속성 설정이 없는 쿠키는 "SameSite=Lax" 로 명시한 것과 동일하게 동작한다는 것입니다.
Specify SameSite=None and Secure if the cookie should be sent in cross-site requests. This enables third-party use.
SameSite 속성은 서로 다른 도메인간의 쿠키 전송에 대한 보안을 설정한다.
A cookie with "SameSite=Strict" will only be sent with a same-site request.
A cookie with "SameSite=Lax" will be sent with a same-site request, or a cross-site top-level navigation with a "safe" HTTP method.
A cookie with "SameSite=None" will be sent with both same-site and cross-site requests.
document.cookie="safeCookie1=foo;SameSite=Lax";
document.cookie="safeCookie2=foo";
document.cookie="crossCookie=bar;SameSite=None;Secure";
JavaScript 사용시, 스크립트 상단에 해당 코드를 선언하면 간단하게 해결할 수 있다.
response.setHeader("Set-Cookie", "Test1=TestCookieValue1; Secure; SameSite=None");
response.addHeader("Set-Cookie", "Test2=TestCookieValue2; Secure; SameSite=None");
response.addHeader("Set-Cookie", "Test3=TestCookieValue3; Secure; SameSite=None");
위의 소스처럼 하나하나 일일이 처리하기 힘든 경우 Filter(필터)나 Interceptor(인터셉터) 등을 사용하여 response를 가로채 Secure; SameSite=None 속성을 추가하여 일괄 변경도 가능하다.
import java.io.IOException;
import java.util.Collection;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
public class CookieAttributeFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
chain.doFilter(request, response);
addSameSite(httpServletResponse , "None");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
private void addSameSite(HttpServletResponse response, String sameSite) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
}
}
}
https://re-man.tistory.com/210
https://ifuwanna.tistory.com/223