Cookie, SameSite

https://seob.dev/posts/브라우저-쿠키와-SameSite-속성/ 을 참고한 글 입니다.

쿠키란 무엇인가?

브라우저에 데이터를 저장하기 위한 수단 중 하나입니다.

브라우저에서 서버로 요청을 전송 할 때, 그 요청에 대한 응답에 Set-Cookie 헤더가 포함되어 있는 경우, 브라우저는 Set-Cookie에 있는 데이터를 저장하고, 이 저장된 데이터를 쿠키라고 부릅니다.

Set-Cookie: normal=yes

서버의 응답에 Set-Cookie 헤더가 포함된 경우, normal이라는 이름의 쿠키에 yes라는 값이 저장됩니다.

그리고 이렇게 저장된 쿠키는 다음에 다시 그 브라우저에서 서버로 요청을 보낼때, Cookie라는 헤더에 같이 전송됩니다. 서버에서는 이 헤더를 읽어서 유저를 식별하는 등 필요한 구현을 할 수 있습니다.

Cookie: normal=yes;

쿠키는 주로 서버에서 사용자를 식별하기 위한 수단으로 사용되어 왔습니다.

Set-Cookie 헤더로 SessionID를 넣어둔 뒤에, 이 후 요청부터 전송될 Cookie 헤더의 SessionID를 읽어 어떤 사용자가 보낸 요청인지 판단하는 식입니다.

많은 웹 사이트의 로그인 구현이 거의 같은 방식으로 구성되어 있습니다.

쿠키에 대한 Domain 설정

쿠키가 유효한 사이트를 명시하기 위해 쿠키에 도메인을 설정 할 수 있습니다.

set-cookie: normal=yes; Domain=localhost

도메인이 설정된 쿠키는 해당 도메인에서만 유효한 쿠키가 됩니다.

normal 쿠키는 localhost를 대상으로 쿠키가 설정되었기 때문에, localhost를 대상으로 한 요청에만 normal 쿠키가 전송됩니다.

쿠키에 별도로 명시된 도메인이 없다면 기본값으로 쿠키를 보낸 서버의 도메인으로 설정됩니다.

퍼스트 파티 쿠키와 서드파티 쿠키

이렇게 설정된 도메인을 기준으로 First-Party Cookies와 Third-Party Cookies로 나뉘어 집니다.

<html>
  <head>
    <title>seob.dev</title>
    <meta property="og:url" content="https://seob.dev/" />
  </head>
  <body>
    <img src="https://example.com/image.png" />
  </body>
</html>

이 코드를 seob.dev라는 사이트의 html 코드라고 가정합니다.

seob.dev라는 도메인으로 들어갔을때, img 태그에 있는 src 속서을 통해 example.com/image.png를 불러옵니다. 만약 사용자가 example.com에 대한 쿠키를 가지고 있다면, 해당 쿠키가 example.com을 운영하는 서버로 같이 전송됩니다. 이 때 전송되는 쿠키를 서드파티 쿠키라고 부릅니다.

서드파티 쿠키는 사용자가 접속한 페이지와 다른 도메인으로 전송하는 쿠키를 말합니다.

seob.dev에 걸려있는 example.com 링크를 클릭한 경우에 전송되는 쿠키도 서드 파티 쿠키로 취급됩니다.

이때 Referer는 seob.dev 입니다.

<html>
  <head>
    <title>seob.dev</title>
    <meta property="og:url" content="https://seob.dev/" />
  </head>
  <body>
    <!-- 아래 링크를 클릭한 경우에 전송되는 쿠키들은 서드 파티 쿠키로 취급됩니다. -->
    <a href="https://example.com/">링크</a>
  </body>
</html>

퍼스트 파티 쿠키는 반대로 이해하면 간단합니다. 사용자가 접속한 페이지와 같은 도메인으로 전송되는 쿠키를 말합니다.

같은 쿠키라도 사용자가 접속한 페이지에 따라 퍼스트 파티 쿠키로도 부를 수 있고, 서드 파티 쿠키로도 부를 수 있습니다. 앞서 말씀드린 예제에서 example.com에 설정된 쿠키는 사용자가 seob.dev에 접속해 있을 때는 서드 파티 쿠키였지만, example.com에 접속해 있을때는 퍼스트 파티 쿠키입니다.

쿠키와 CSRF 문제

쿠키에 별도로 설정을 가하지 않는다면, 크롬을 제외한 브라우저들은 모든 HTTP 요청에 대해서 쿠키를 전송하게 됩니다. 그 요청에는 HTML 문서 요청, HTML 문서에 포함된 이미지 요청, XHR 혹은 Form을 이용한 HTTP 요청등 모든 요청이 포함됩니다.

CSRF(Cross Site Request Forgery)는 이 문제를 노린 공격입니다.

SameSite 는 이 문제를 해결하기 위해 탄생한 기술입니다.

SameSite 쿠키

SameSite 쿠키는 앞서 언급한 서드 파티 쿠키의 보안적 문제를 해결하기 위해 만들어진 기술입니다.

크로스 사이트(Cross-Site)로 전송하는 요청의 경우 쿠키의 전송에 제한을 두도록 합니다.

SameSite 쿠키의 정책으로, None, Lax, Strict 세 가지 종류를 선택할 수 있고, 각각 동작하는 방식이 다릅니다.

  • None: SameSite가 탄생하기 전 쿠키와 동작하는 방식이 같습니다. None으로 설정된 쿠키의 경우 크로스사이트 요청의 경우에도 항상 전송 됩니다. 서드파티쿠키도 전송됩니다. 따라서, 보안적으로도 SameSite 적용을 하지 않은 쿠키와 마찬가지로 문제가 있는 방식입니다.
  • Strict: 가장 보수적인 정책. Strict로 설정된 쿠키는 크로스 사이트 요청에는 항상 전송되지 않습니다. 서드 파티 쿠키는 전송되지 않고, 퍼스트 파티 쿠키만 전송됩니다.
  • Lax: Strict에 비해 상대적으로 느슨한 정책. Lax로 설정된 경우 대체로 서드파티 쿠키는 전송되지 않지만, 몇 가지 예외적인 요청에는 전송됩니다.

Lax 쿠키가 전송되는 경우

https://seob.dev/posts/브라우저-쿠키와-SameSite-속성/#lax-쿠키가-전송되는-경우 에 잘 정리되어 있으니 읽어보시길 바랍니다.

브라우저의 SameSite 구현

Lax by default

크롬은 SameSite를 가장 적극적으로 적용하고 있는 브라우저입니다. SameSite가 명시하지 않은 쿠키는 SameSite가 None으로 동작했지만, 2020년 2월 4일 크롬 80 버전이 배포되면서 SameSite의 기본값이 Lax로 변경되었고 이 변경사항은 운영되고 있는 웹 서비스들에게 많은 영향을 미쳤습니다.

더 자세한 이야기는 https://seob.dev/posts/브라우저-쿠키와-SameSite-속성/#lax-by-default 에서 파악하실 수 있습니다.

Secure 필수 정책

SameSite 속성으로 None을 사용하려면 반드시 해당 쿠키는 Secure 쿠키여야 합니다.

Secure 쿠키는 HTTPS가 적용된(그러니까 암호화된) 요청에만 전송되는 쿠키입니다.

이 정책을 구현하는 브라우저도 현재는 크롬밖에 없습니다.

그래서 크롬에서는 SameSite=None 으로 Set-Cookie를 사용하면 다음과 같이 쿠키 자체가 제대로 설정되지 않습니다.

set-cookie: same-site-none (non-secure)=yes; SameSite=None

← Go home