본문 바로가기
공부/기타등등

[web] 쿠키의 동작

by 야옹아옹 2023. 1. 6.
해당 글은 web.dev의 SameSite 쿠키 설명 글을 제가 이해하기 쉬운 방향으로 다시 정리한 글 입니다.
원본 글을 읽으시는 걸 추천합니다.


🍪 쿠키란?

웹 사이트를 방문했을 때, 웹 브라우저를 통해 사용자의 로컬 환경설치되는 작은 기록 정보 파일

HTTP 프로토콜에 속한다.

서버가 보내주는 데이터이다.

🍪 쿠키를 사용하는 경우

  • 세션 관리
    • 서버에서 저장해야하는 세션 정보를 관리한다. 민감한 정보 X. ex) 세션ID
  • 개인화
    • 사용자 선호, 테마 등을 관리한다
  • 사용자 트래킹
    • 사용자의 행동을 기록하고 분석

🍪 first-party 및 third-party 쿠키

  • first-part 쿠키
    • 현재 사이트의 도메인, 브라우저 주소 표시줄에 표시되는 도메인과 일치하는 쿠키를 first-party 쿠키라고한다.
  • third-party 쿠키
    • 현재 사이트가 아닌 다른 도메인의 쿠키를 third-party 쿠키라고 한다.

같은 도메인same-site인 경우 예시

더보기
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions

🍪 session 쿠키와 permanent 쿠키

  • session 쿠키
    • 브라우저를 종료하면 사라진다.
    • MaxAge나 Expires 옵션이 없는 쿠키로, 브라우저가 실행 중일 때 사용할 수 있는 임시 쿠키
  • permanent 쿠키
    • 브라우저의 종류 여부와 상관없이 maxAge 또는 Expires에 지정된 유효시간만큼 사용가능한 쿠키

🍪 쿠키의 동작

아래에 사용된 예시는 구글의 sameSite 쿠키 설명에서 가져왔다. 

같은 도메인인 경우 sameSite

1. 브라우저로 웹 사이트를 방문한다.
새로운 기능 프로모션을 하려는 블로그에 방문한다. 사용자는 프로모션을 닫을 수 있고, 그러면 프로모션 창을 잠시 동안 다시 볼 수 없다.
프로모션을 닫았다는 설정쿠키에 저장하고, 쿠키가 한 달 후에 만료되도록 설정해준다.

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure

https://web.dev/samesite-cookies-explained/#explicitly-state-cookie-usage-with-the-samesite-attribute

2. 사용자가 한달 내로 다시 웹사이트(블로그)를 방문했을 때,

브라우저는 웹사이트 요청에 이전에 저장한 쿠키를 헤더에 넣어서 보낸다. 헤더에 넣어서 보내는 쿠키는 1에서 저장한 프로모션을 닫았다는 설정을 가진 쿠키다.

Cookie: promo_shown=1

이후에 응답으로 돌아온 웹사이트는 프로모션이 닫힌 상태로 오게 된다.

다른 도메인인 경우

같은 도메인인 경우에서 사용했던 블로그에서 고양이 사진이 있고, 해당 이미지는 /blog/img/amzing-cat.png에서 호스팅되고 있다고 가정한다.
이 고양이 이미지가 너무 귀여워서 다른 사람이 자신의 사이트에 이 이미지를 직접 사용하기로 한다.

고양이 이미지를 호스팅하는 도메인A도메인이라고 하고, 이 이미지를 사용한 개인 사이트의 도메인을 B도메인이라고 한다.

이때, B도메인 사이트의 방문자가 A도메인 사이트(블로그)를 방문한 적이 있어서 promo_shown 쿠키가 있는 경우,

B도메인 사이트에서 amzing-cat.png를 볼 때, 이 이미지를 가져오는 요청에서 해당 쿠키 promo_shown가 전송된다.

즉, 이미지 리소스를 요청할 때, 쿠키가 같이 보내진다.

이는 사이트가 다른 사이트에서 사용될 때,  상태를 유지할 수 있도록 하는 메커니즘이다.

  • 예를 들어, 사이트에 유튜브 동영상을 삽입했고 해당 사이트의 방문자가 이전에 유튜브에 로그인이 되어서 관련 쿠키가 있는 경우. 사이트에서 유튜브 동영상을 요청할 때, 해당 쿠키(유튜브 서버에서 제공한)도 함께 보내기때문에 다른 사이트에 있는 유튜브 동영상에서 나중에 보기 옵션이 표시되는 것이다.
    즉, 나중에보기 버튼을 눌러도 다시 유튜브 로그인을 하거나 페이지 다른 곳으로 이동할 필요 없이 한 번에 동영상이 나중에 보기로 저장된다.

문제는 위와 같은 메커니즘이 사이트 간 요청 위조 공격 CSRF에 취약하다는 점이다.
이 공격은 쿠키가 지정된 출처에 대한 모든 요청에 첨부된다는 사실을 악용한다.
예시) your-blog.com 쿠키를 가지고 있는 상태에서 악성 사이트에서는 접속 시, your-blog.com에 요청이 트리거될 수 있고 브라우저는 기꺼이 관련 쿠키를 함께 첨부해 요청을 보낼 것이다. 만약, 서버가 이런 요청을 검증하지 않는다면 악성 사이트는 내 쿠키를 사용해 게시물을 삭제하거나 자체 콘텐츠를 추가하는 작업을 트리거 할 수 있다.

이와 같은 문제를 막기 위해서 쿠키에 sameSite 옵션을 사용하면 좋다. 크롬 브라우저의 기본 쿠키의 sameSite 특성은 Lax이다.

 

🍪 sameSite

sameSite = Strice인 경우

쿠키가 자사 컨텍스트에서만 전송된다.

쿠키는 해당 사이트가 현재 브라우저의 URL 표시줄에 표시된 사이트와 일치하는 경우만 전송한다.

Set-Cookie: promo_shown=1; SameSite=Strict

사용자가 내 사이트에 있으면 예상대로 요청과 함께 쿠키가 전송된다.

그러나 다른 사이트에서는 또는 친구의 이메일을 통해 내 사이트로 연결되는 링크를 따라가는 경우, 이 초기 요청 시 쿠키가 전송되지않는다.

비밀번호 변경 또는 구매와 같은 기능과 관련된 쿠키라면 이렇게 동작해야하지만 프로모션 보기 유무와 같은 쿠키에 사용하기엔 너무 제한적이다.

sameSite = Lax인 경우

독자가 이 링크를 따라 사이트로 들어온 경우에는 기본 설정을 적용할 수 있도록 쿠키가 전송되기를 원한다면 Lax를 쓰면된다.

Strict 정책에서 예외 처리가 몇개 된 정책이다.
1. Same-site인 경우 쿠키를 전송할 수 있다.
2. Cross-site인 경우 top-level navigation이면서 safe한 HTTP 메서드를 사용해야한다.

일반적인 사이트 간 하위 요청(ex. 이미지 or iframe 로드)에는 쿠키는 전송되지않지만, 사용자가 원본 사이트를 탐색할 때(링크를 이동할 때) 전송된다.

 

Safe HTTP request란?

  • HTTP 메서드가 서버의 상태를 바꾸지 않으면 그 메서드가 안전하다고 한다.
  • ex) GET, HEAD, OPTIONS

top-level navigation이란?

  • 사용자가 링크를 클릭하거나(a태그 href), window.location.rep

다른 사이트에서 내 콘텐츠를 참조하는 고양이 사진을 다시 예시로 들면

<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
Set-Cookie: promo_shown=1; SameSite=Lax

독자가 다른 사람의 블로그에 있을 때, 브라우저가 amazing-cat.png 이미지요청하면 쿠키가 전송되지않는다.

그러나 독자가 블로그의 cat.html 링크따라가면 해당 요청에는 쿠키가 포함된다.

sameSite = None인 경우

과거에 쓰였던 Default 정책으로 Samesite 검증을 진행하지않는다.
- 이전에 모든 컨텍스트에서 쿠키가 전송되기를 원한다는 설정이다.
- 위험하기 때문에 항상 https(secure=true)에서만 사용할 수 있다.

즉, 의도적으로 다른 도메인에서 쿠키가 전송되기를 원한다는 사실을 명확하게 전달한다.

ex) 사이트에 유튜브 영상을 iframe으로 가져오는 요청에 유튜브의 쿠키를 함께 보내서 로그인 된 상태의 iframe정보를 가져올 수 있다.

댓글