Post

SameSite Cookie

쿠키(Cookie)와 저장소(Storage)

SameSite cookies explained

https://web.dev/samesite-cookies-explained/

  • 브라우저는 도메인 별로 쿠키를 저장하고 있다. 따라서 다른 도메인으로 이동한다고 해서 쿠키가 삭제되지 않는다.
  • 다른 사이트 갔다가 돌아왔을 때, 로그인 상태가 유지되는 것은 브라우저가 해당 도메인의 세션 쿠키를 다시 꺼내기 때문이다.
  • 어떤 도메인에 요청할 때, 브라우저는 해당 도메인의 쿠키를 꺼내 헤더에 포함하여 전송하도록 되어 있다.
  • 내가 현재 도메인 A에 있고, 페이지 내에 삽입된 이미지는 외부 도메인 B의 데이터다.
  • 이미지를 불러오기 위하여 외부 도메인 B로 요청한다.
  • 이 때 B에 속하는 쿠키가 있다면 쿠키가 헤더에 포함돼서 전송된다.
  • 이를 third-party cookie 라고 부른다. (cross-site request)
  • 반면 현재 내가 위치한 도메인의 쿠키는 first-party cookie 라고 부른다. (same-site request)
thrid-party cookie는 다음과 같은 상황에서 유용하다.

내 사이트에 youtube 동영상을 삽입해 두었고,삽입된 youtube 동영상 플레이어에서 유저가 “나중에 보기”버튼을 눌렀다고 가정해보자.

“나중에 보기” 정보는 계정에 저장되는 것이기 때문에 유튜브 계정이 필요하므로 원래대로라면 로그인 페이지로 연결되어야 한다.

허나 만약 이전에 유튜브에 로그인을 했었고, 그 세션 쿠키가 살아있는 상태라면? “Watch later” 버튼을 눌렀을 때 youtube에 요청이 갈 텐데 세션 쿠키가 있으므로 자동으로 인증이 처리된다.

그래서 별도의 로그인 없이 해당 계정에 비디오를 저장할 수 있다는 것이다.

여기서 의미하는 Site란?
  • 도메인 전체에서, domain suffix를 포함하여 그 직전 부분까지를 잘라서 site로 구분한다.
  • domain suffix는public suffix 에서 확인 가능하다. ```

com은 public suffix에 명시되어 있으므로, domain suffix다. domain suffix를 포함하여 그 직전 부분까지가 site이므로, (\d+.)*xxx.com 를 하나의 site로 본다. same-site naver.com www.naver.com static.naver.com a.b.c.naver.com

cross-site naver.com facebook.com

github.io는 public suffix에 명시되어 있으므로 domain suffix다. xxx.github.io를 하나의 site로 본다. same-site aaa.github.io static.aaa.github.io

cross-site aaa.github.io bbb.github.io ```

SameSite 옵션

  • “어떤 쿠키를 same-site request인 경우만 전송할건지, third-party request인 경우도 전송할건지”를 명시하는 것이 SameSite 옵션이다.
  • 옵션은 3개다. None, Strict, Lax
  • 명시하지 않으면 Default 값으로 설정된다.
  • 크롬 80 버전 이전까지는 Default=None이었으나, 80부터 Default=Lax가 된다.
  • 또한 None으로 지정하는 경우, Secure옵션을 같이 명시해주어야 한다. 안그럼 reject된다.

  • Strict : 요청 사이트가 현재 사이트와 same-site 인 경우에만 쿠키를 포함해서 전송.
  • Lax | None일 때는 아래와 같이 요청 종류에 따라 쿠키를 포함할지 안할지가 다르다. (link )
  • top-level POST에 대해서는 cookie를 허용하자는 논의 가 있었음.
   
Request TypeSample CodeCookies Sent
Link<a href="..."></a>Normal, Lax
Prerender<link rel="prerender" href=".."/>Normal, Lax
Form GET<form method="GET" action="...">Normal, Lax
Form POST<form method="POST" action="...">Normal
iframe<iframe src="..."></iframe>Normal
AJAX$.get("...")Normal
Image<img src="...">Normal
  • SameSite 요청인지 CrossSite 요청인지 판단은 현재 브라우저 주소 창에 떠있는 도메인을 기준으로 한다.
  • 주소 창에는 naver.com인데, iframe 내에서 facebook.com 이면 cross-site
  • iframe 내에서 페이지를 이동할 때에도 브라우저는 쿠키를 꺼내줄지 안줄지를 본다.
  • 그래서 iframe내에서 facebook.com(쿠키세팅) -> facebook.com 하게 되면 쿠키가 전달되지 않는다. 현재 주소 창을 기준으로 cross-site이기 때문.

CSRF 막는데 사용할 수 있다.

https://imjuno.com/author/imjuno99/

  • CSRF라는건 결국 세션 쿠키를 이용해서 해당 유저의 권한으로 서버에 요청하는 공격이다.
  • SameSite 옵션으로 인해서 타 사이트->공격 대상 사이트로 요청할 때 쿠키가 포함되지 않도록 할 수 있다.
  • 세션 쿠키가 포함되지 않으니 해당 유저의 권한으로 요청하는 것이 불가능하다.
  • vulnsite.com -> naver.com으로 이동할 때는 네이버측 쿠키를 꺼내주지 않는다는 것.
  • 다만 이렇게 이동한 naver.com에서 다시 naver.com으로 이동할 때는 쿠키를 꺼내준다. 왜냐면 브라우저 URL이 naver로 변경되었으니까 SameSite
  • naver에서는 이를 이용하여 일단 naver.com으로 온 다음에 다시 쿠키가 필요한 naver.com 페이지로 redirect하는 식으로 쿠키를 꺼낼 수 있다.
  • redirect는 GET요청이므로, POST가 필요하다면 별도의 form 페이지를 만들어서 그 페이지를 거치는 방법이 있다.
This post is licensed under CC BY 4.0 by the author.