쿠키(cookie)는 서버가 사용자의 웹 브라우저에 'Key:Value' 형태로 전송하는 작은 데이터 조각으로, 브라우저는 이런 문자열 데이터 조각들을 저장해두었다가 동일한 서버로의 request마다 쿠키 데이터를 전송한다.
따라서 HTTP 서버는 기본적으로 무상태(stateless)이기 때문에 상태를 보존할 수 없지만, 쿠키를 통해서 기존의 정보를 그대로 이용할 수 있다는 뜻이다.
Cookie의 목적
HTTP 서버는 무상태를 통해 서버 설계를 간편하게 하고 동시에 수천 개의 TCP 연결을 다룰 수 있는 고성능의 웹 서버를 개발할 수 있다. 그런데 우리는 종종 웹 사이트가 사용자를 확인하는 것이 바람직할 때가 존재하기 때문에 쿠키를 사용해야만 할 때가 있다. 그중 가장 많이 사용하는 목적은 다음과 같다
- 개인화: 사용자에 따라 다른 콘텐츠를 제공하거나 사용자의 이전 기록을 저장해둘 때 (ex. 웹사이트에 설정한 언어, 테마, 관심사 등)
- 세션 관리: 로그인 상태, 장바구니 정보 등의 세션 정보를 유지할 때
- 추천 및 분석: 사용자의 행동을 기록하고 분석하여 마케팅에 사용하기 위해 (ex. 분석데이터 수집, 리타게팅 광고)
이외에도 서버가 사용자의 접속을 제한하거나 기기 식별 등의 이유로도 사용된다
Cookie 관리
그렇다면 쿠키 설정을 서버에서 해주는 것이므로 서버에서 관리하는걸까? 그렇지 않다. 쿠키는 전적으로 웹 브라우저가 관리한다. 이는 쿠키가 웹 브라우저에 종속되어있단 뜻이므로, Chrome이나 Edge, Whale 등 서로 다른 브라우저에서는 같은 쿠키 값이더라도 다른 쿠키라는 뜻이다.
- 쿠키는 웹 브라우저에서 관리한다 (웹 브라우저에 종속되어있다)
- 웹 사이트 도메인, 혹은 페이지 경로에 종속되게 저장할 수 있다 (ex. 서버에서 path=/home에 쿠키를 저장했다면 /test에서는 사용할 수 없다)
- 브라우저에서 직접 쿠키를 확인하거나 삭제할 수 있다 (ex. 크롬의 경우 개발자 모드 -> application 탭 -> cookies에서 관리 가능)
- 쿠키의 생성은 서버와 클라이언트 모두에서 생성할 수 있다
Cookie의 생성 및 사용
쿠키 기술에는 'HTTP 응답 메시지 쿠키 헤더 라인', 'HTTP 요청 메시지 쿠키 헤더 라인', '브라우저의 쿠키 파일', '백엔드 서버' 와 같은 총 네 개의 요소로 이루어져있다. 생성 및 사용 과정을 'Amazon'에 접속한 유저를 통해 알아보자.
- 과거에 이미 'eBay'에 방문한 적 있던 유저가(이미 eBay의 식별 번호가 쿠키에 저장되어있음) 'Amazon'에 처음으로 접속한다
- 'Amazon' 클라이언트에서 서버로 request를 보낸다
- 'Amazon' 서버에서는 유저에 대한 고유한 값(식별 번호)을 생성하여 쿠키에 저장한다
이때 서버에서는 response의 'Set-cookie' 라는 헤더를 사용하여 쿠키에 원하는 데이터를 저장할 수 있다 - 이제 client에서는 'Amazon' 서버에 request를 보낼 때마다 'cookie' 헤더에 식별 번호를 저장해서 보내게 된다.
물론 여기서 서버로 보내는 식별번호는 'eBay' 식별 번호가 아니라 'Amazon' 식별 번호이다
쿠키의 속성
다음 속성들은 Cookie를 생성할 때 설정해줄 수 있다
1. Path
- 특정 경로에서만 쿠키에 접근할 수 있도록 설정하는 옵션이다
- 경로를 설정해주면, 설정한 경로의 하위 경로에서도 접근할 수 있다
(ex. path = /test 라면, /test, /test/1, /test/path/5 에서 모두 접근 가능)
2. Domain
- 특정 도메인에서만 접근할 수 있도록 설정하는 옵션이다
- domain에 아무 값도 설정하지 않았다면, 서브 도메인에서는 쿠키에 접근할 수 없다
3. MaxAge
- 쿠키의 만료 기간을 설정한다
- 만약 설정해주지 않는다면, 브라우저를 닫을 때 쿠키가 삭제된다 (세션쿠키)
- MaxAge를 0으로 설정하면 쿠키가 바로 삭제된다
4. HttpOnly
- 쿠키는 클라이언트에서 JavaScript를 통해 조회할 수 있다
- 그러나 이로 인해 XSS(Cross Site Scripting) 공격이 이루어질 수 있다
- 따라서 'HttpOnly' 속성을 통해 JavaScript로 쿠키에 접근할 수 없도록 하여 XSS 공격을 예방할 수 있다
5. Secure
- HttpOnly 속성을 사용하면 XSS를 예방할 수는 있지만, 네트워크를 직접 감청하여 Cookie를 가로채는 위험을 막지는 못한다
- 따라서 HTTPS 프로토콜에서만 쿠키를 전달하도록 하는 secure 옵션을 통해 이를 예방할 수 있다
6. SameSite
- CSRF(Cross-Site Request Forgery) 공격 및 의도하지 않은 정보 유출을 막기 위한 옵션
- 서로 다른 도메인간의 쿠키 전송에 대한 보안을 설정한다. 보안 정도는 다음 세 개의 전략이 있다
- None: Same-Site와 Cross-Site 모두 쿠키 전송이 가능
- Strict: Cross-Site에서는 전송이 완전히 불가능. CSRF를 완전히 방지할 수 있지만 사용자 편의성을 많이 해치게 됨
- Lax: Strict 설정에서 일부를 허용해주는 전략(Http Get 메서드, <a> 태그의 href 속성 등)
Reference
- 컴퓨터 네트워킹 하향식 접근(제 7판, 2.24 사용자와 서버 간의 상호작용: 쿠키)
- Cookie의 기본 개념: https://pygmalion0220.tistory.com/entry/HTTP-Cookie-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90
- 웹 브라우저의 Cookie 헤더 다루기: https://inpa.tistory.com/entry/HTTP-%F0%9F%8C%90-%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BF%A0%ED%82%A4-%EA%B0%9C%EB%85%90-Cookie-%ED%97%A4%EB%8D%94-%EB%8B%A4%EB%A3%A8%EA%B8%B0
- Http Only와 Secure Cookie 이해하기: https://nsinc.tistory.com/121