SameSite Cookie
SameSite cookies explained
https://web.dev/samesite-cookies-explained/
first-party cookie와 third-party cookie
- 브라우저는 도메인 별로 쿠키를 저장하고 있다. 따라서 다른 도메인으로 이동한다고 해서 쿠키가 삭제되지 않는다.
- 다른 사이트 갔다가 돌아왔을 때, 로그인 상태가 유지되는 것은 브라우저가 해당 도메인의 세션 쿠키를 다시 꺼내기 때문이다.
- 어떤 도메인에 요청할 때, 브라우저는 해당 도메인의 쿠키를 꺼내 헤더에 포함하여 전송하도록 되어 있다.
- 내가 현재 도메인 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 Type | Sample Code | Cookies 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 페이지를 만들어서 그 페이지를 거치는 방법이 있다.