웹 개발자의 적 SameSite, 그만 보고 싶은데 어떻게 없애?

익스랩 최고 관리자

·

2020. 8. 26. 16:16

반응형

<이미지 저작권 : 디자이프x익스랩>

 

우선 SameSite란 왜 생기는 걸까? 

 

2020년 2월 4일에 릴리즈 된 구글 크롬(Google Chrome) 80버전부터 새로운 쿠키 정책이 적용되었다는 걸 알고 계신가요? 릴리즈 내용에 따르면 Cookie의 SameSite 속성의 기본값이 "None"에서 "Lax"로 변경되었습니다.

 

이는 SameSite를 None으로 설정할 경우 CSRF(Cross-site request forgery - 사이트 간 요청 위조) 및 의도하지 않은 정보 유출에 취약해질 가능성을 높게 판단해 변경된 사항이라고 하는데요. 이런 취약성을 방지하기 위해 별도의 SameSite 속성 명시 없이 쿠키를 생성했을 경우, 새롭게 릴리즈 된 Chrome80 버전 이후부터 SameSite 속성 설정이 없는 쿠키는 "SameSite=Lax"로 명시한 것과 동일하게 동작하도록 했습니다.

 

<참고 이미지>

이후 Firefox, Edge 등 다른 브라우저도 Chrome 과 동일한 설정으로 기본값을 설정한다고 하니 내용을 알아두시면 좋을 것 같네요.

 

 

 

SameSite

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.

 

1. "None"으로 설정할 경우, 동일 사이트과 크로스 사이트에 모두 쿠키 전송이 가능합니다.

2. "Strict"으로 설정할 경우, 서로 다른 도메인에서는 아예 전송이 불가능해 집니다.

      따라서, CSRF를 100% 방지할 수 있으나 사용자 편의성을 많이 해치게 됩니다.

3. "Lax"으로 설정할 경우, Strict 설정에 일부  예외( HTTP get method / a href / link href )를 두어 적용되는 설정입니다.

 

웹 개발시, 크로스 도메인간 중요한 정보 유지는 CSRF 가능성이 있는 쿠키가 아닌 다른 안전한 방식으로 하기를 권장합니다. 하지만 쿠키의 의존성을 낮추는 것이 힘들 경우, 쿠키의 SameSite설정을 기존의 기본값이었던 None으로 설정하여 임시로 해결 할 수 있습니다.

 

 

 

SameSite 설정하기

SameSite 속성을 변경하는 방법은 쿠키 생성하는 시점부터 설정해 주거나 필터 등을 이용하여 기존 쿠키에 속성을 추가하는 방법이 있습니다. 만약 Apache 같은 HTTP 서버를 사용중이라면 서버 설정을 통해 일괄로 변경하는 것도 가능합니다.

 

 

This set-cookie had the "SameStie=None" attribute but did not have the "Secure" attribute.

which is required in order to use "SameSite=None" 

 

 

 

1. JavaScript를 활용하여 수정하기

document.cookie = "safeCookie1=foo; SameSite=Lax"; 
document.cookie = "safeCookie2=foo";  
document.cookie = "crossCookie=bar; SameSite=None; Secure";

 

 

JavaScript 사용시, 상단에 해당 소스를 선언하여 간단하게 해결된 것을 볼 수 있습니다.

 

주의점

* SameSite 속성을  None으로 설정할 경우  Secure 속성을 함께 추가해야 합니다.

Secure 속성을 추가된 쿠키는 HTTPS 프로토콜에서만 전송이 가능합니다.

SameSite가 None이지만 Secure 속성이 없을 경우 브라우저에서는 아래의 경고 메시지와 함께 해당 쿠키를 적용하지 않습니다.

This set-cookie had the "SameStie=None" attribute but did not have the "Secure" attribute.which is required in order to use "SameSite=None" 

 

 

 

2. Java Application 을 활용하여 수정하기

java에서 많이 사용하는 javax.servlet.http.Cookie Class에서는 SameSite 관련 API를 지원하지 않습니다. 따라서 HttpServletResponse 의 response 객체에 Set-Cookie 헤더(Header)를 직접 추가해 주셔야 합니다.

 

 

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");

 

주의점

*setHeader 를 통해 Set-Cookie 헤더를 처음 추가한 뒤 setHeader를 다시 사용할 경우,

동일이름의 헤더가 오버라이드 되기 때문에 첫 추가 이후에는 addHeader를 통해 추가 해야 합니다.

 

만약 Spring Core 5.0 이상 버전을 사용중이시라면  org.springframework.http.ResponseCookie Class의 API 를 사용하여 조금 더 쉽게 처리가 가능합니다.

 

ResponseCookie cookie = ResponseCookie.from("sameSiteCookie", "sameSiteCookieValue")
            .domain("ifuwanna.tistory.com") 
            .sameSite("None")
            .secure(true)
            .path("/")
            .build();
response.addHeader('Set-Cookie', cookie.toString());

 

 

 

 

 

3. Filter or Interceptor

위처럼 소스상에서 하나하나 처리가 힘든 경우 Filter(필터)나 Interceptor(인터셉터) 등을 이용하여 response를 가로채 Secure; SameSite=None 속성을 추가하여 일괄 변경도 가능합니다.

 

 

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);
    log.info("CookieAttributeFilter");		
    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));
    }
  }
}

 

 

 

 

 

4. Tomcat 설정

Tomcat WAS에서 지원하는 Cookie Processor Component를 사용하여 일괄 쿠키 속성 추가가 가능합니다.

-> context.xml

<Context>
  ...
  ...
  <CookieProcessor sameSiteCookies="none"/>
</Context>

 

 

 

5. Web Server 설정 [HTTP Server]

Apache 같은 HTTP 웹서버를 이용중이라면, 모든 쿠키 속성을 한 번에 변경 할 수 있습니다.

-> Apach Configuration

Header always edit Set-Cookie (.*) "$1; Secure SameSite=None;"
반응형

💖 포스터에게 힘 보내기 💖

카카오뱅크
3333-25-9477515
치킨 좋아하는 포스터