예를 들어 웹 사이트에 로그인한다고 가정해보자. 로그인을 성공적으로 하고 나면 서버는 클라이언트에 일종의 인증서 같은 걸 보내준다. 클라이언트가 이걸 가지고 오면 어떤 사람인지 구분하는데 사용하기도 한다. 클라이언트는 request를 보낼 때마다 이 인증서를 request에 함께 포함해서 보내야 하는데, 이때 사용하는 것이 쿠키(Cookie)이다.
로그인에 성공했을 때 서버가 Set-Cookie 헤더로 쿠키 값을 보내주면 이걸 클라이언트가 저장해 두었다가, 서버에 request를 보낼 때마다 매번 Cookie 헤더로 보내서 로그인 된 상태라는 걸 표현한다. 웹 브라우저를 껐다 키거나 컴퓨터를 껐다 키더라도 쿠키 값은 유지되기 때문에 평소에 사이트를 한 번 로그인하면, 일정 기간 동안은 로그인하지 않아도 로그인이 유지된다.
서버에서 set-cookie 헤더를 response로 보내주면 웹 브라우저는 알아서 쿠키 값을 저장해 둔다.
Set-Cookie: session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;
맨 앞의 session-id는 쿠키의 Key에 해당하는 값이고, 1234는 Value에 해당하는 값이다. domain, path, samesite 등은 쿠키의 Attribute에 해당하는 값이다. (헤더 이름이나 Attribute 이름들은 대소문자를 구분하지 않기 때문에 set-cookie, domain, path, smaesite로 쓸 수도 있다.)
request를 보낼 때 주소가 해당하는 쿠키가 저장되어 있다면 웹 브라우저가 알아서 쿠키를 보내준다.
Cookie: session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;
보통은 서버가 쿠키 값을 만들고, 클라이언트에서는 웹 브라우저에 맡기고 건드리지 않는 것이 권장된다. 하지만 클라이언트에서 자바스크립트로 쿠키를 생성/수정/참조할 수도 있다.
session-id라는 쿠키가 있다면) 수정하는 코드이다.document.cookie = "session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;";Max-Age 값을 0으로 업데이트하면 (수명이 0) 지워진다.document.cookie = "session-id; Max-Age: 0;";브라우저가 쿠키를 보낼 도메인을 지정한다. 예를 들어 Domain=codeit.kr이라고 하면 https://codeit.kr은 물론이고 https://abc.codeit.kr, https://xyz.abc.codeit.kr 같은 서브 도메인에 request를 할 때도 쿠키를 보낸다.
브라우저가 쿠키를 보낼 경로를 지정한다. 예를 들어 Path=/라고 하면 / 아래에 있는 경로들, /abc, /abc/xyz같은 경로에 request를 보낼 때에도 모두 쿠키를 보낸다.
document.cookie 값을 자바스크립트로 사용할 수 있으면, 악성 코드를 사용자들에게 유포해 쿠키를 훔칠 수 있다.
로그인 정보 같은 민감한 정보는 되도록이면 자바스크립트로 조작하지 마라. HttpOnly를 사용하면 쿠키를 자바스크립트로 사용하지 못하게 막을 수 있다.
Secure를 지정하면 HTTPS request를 보낼 때만 쿠키를 보낸다. 참고로 SameSite=Non을 지정하면 반드시 Secure도 함께 지정해야 한다.
자바스크립트를 사용하면 현재 사이트에서 다른 사이트로 request를 보낼 수 있고, 사이트의 링크를 클릭하면 웹 브라우저는 다른 사이트로 GET request를 보내며 이동한다. 그리고 이미지 파일을 다운 받거나 할 때도 GET request를 보내서 받는다.
예를 들어 codeit.kr이라는 사이트에서 쿠키를 발급해서 사용자가 저장하고 있는데, 사용자가 hacker-site.com이라는 악성 사이트에 접속한다고 가정하자. 악성 사이트는 codeit.kr이라는 사이트로 request를 보내서 개인정보를 탈취하는 사이트이다. 악성 사이트에서 코드잇으로 request를 보낼 때 쿠키가 할께 간다면 개인정보가 악용될 수 있다.
이런 공격을 크로스 사이트 요청 위조(Cross-site request forgery, CSRF, XSRF)라고 한다. XSRF를 방지하기 위해서 제3자 사이트(Third-party site)에서 쿠키를 보내지 못하게 SameSite를 지정해야 한다,
SameSite 속성의 값에는 Strict, Lax(아무것도 지정하지 않았을 때 기본값), None이 있다. 다음은 SameSite 값에 따른 쿠키 전송 유무를 정리한 표이다.
| SameSite = Strict | SameSite = Lax | SameSite = None | |
|---|---|---|---|
| 다른 사이트엣 우리 사이트로 request를 보낼 때 | X | X | O |
| 다른 사이트에서 이미지 파일 등을 받을 때 | X | X | O |
| 다른 사이트에서 사용자가 링크를 클릭해 사이트로 이동할 때 | X | O | O |
| 사이트에서 사이트로 request를 보낼 때 | O | O | O |
쿠키의 수명을 지정하는 속성이다. Expires로 만료될 시기를 지정하거나, Max-Age로 쿠키의 수명을 지정할 수 있다.
Expires나 Max-Age를 지정하지 않으면 만들 수 있다. 세션 쿠키는 바라우저를 닫으면 지워지는 쿠키이다.Expires나 Max-Age로 수명을 지정해서 만들 수 있다. 수명이 다하면 지워지는 쿠키이다.예전에 구글, 페이스북 등 빅테크들이 쿠키를 사용해서 사용자의 정보를 과도하게 수집하고 자사 광고에 활용해 논란이 된 적이 있다. 그래서 유럽 연합에서는 개인정보의 범위를 넓혀 직간접적으로 개개인을 식별할 수 있는 데이터까지 개인정보로 규정을 만들었다. 여기에 쿠키 데이터도 포함된다.
따라서 쿠키를 사용하는 경우 GDPR(일반 정보 보호 규정 : General Data Protection Regulation) 규정에 따르면 개인정보 이용목적을 안내하고 사용자이 동의를 받는 등의 절차가 필요하다. 그래서 최근 많은 사이트들이 처음 들어가면 팝업을 띄우고 동의를 받는다.
[모비랩의 테크인사이드] 마케터라면 필수적으로 알아야 할 'GDPR(일반 정보 보호 규정)' 이해 - 모비인사이트 MOBIINSIDE
쿠키, 세션, 캐시가 뭔가요?
HTTP 쿠키 - HTTP | MDN
Set-Cookie - HTTP | MDN
브라우저 쿠키와 SameSite 속성 / seob.dev
react-cookie 쉽게 사용하기
Cross Site Request Forgery (CSRF) | OWASP Foundation