본문 바로가기

HTTP

[HTTP] HTTP 쿠키

HTTP 쿠키는 클라이언트-서버 간 상태를 유지를 위해 서버가 클라이언트에 저장시키는 작은 데이터 조각이다.

이후 요청마다 자동으로 서버에 전송되어, 사용자를 식별하거나 세션 관리, 광고 정보 트래킹, 사용자 맞춤 설정 등을 가능하게 한다.

 

 


🔷 쿠키의 기본 개념

  • HTTP는 상태를 유지하지 않는(Stateless) 프로토콜 → 상태를 유지하기 위해 쿠키 사용!
  • 쿠키는 클라이언트 측(브라우저)에 저장된다. → 일반적으로 브라우저의 쿠키 저장소(DB)에 저장
  • 저장된 쿠키는 항상 서버에 전송된다. → 추가적인 네트워크 트래픽을 유발!
  • 따라서, 쿠키는 최소한의 정보만 사용해야 한다. (session ID, 인증 토큰)

 

 


🔷 쿠키의 기본 흐름

 

📌 서버 → 클라이언트 (Set-Cookie)

HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure

 

📌 클라이언트 → 서버 (Cookie)

GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123

 

이처럼 클라이언트는 쿠키를 헤더에 포함시켜 서버로 전송함으로써, 세션 등을 유지할 수 있다.

 

 

⚠️ 실전 유의사항

  • Set-Cookie 응답마다 여러 개 보낼 수 있다.
  • 같은 이름의 쿠키마지막 설정이 우선 적용된다.
  • 쿠키 크기 제한: 1개당 약 4KB, 도메인당 약 20~50개

 

 


🔷 쿠키의 종류

 

HTTP 쿠키는 속성에 따라 다양한 분류로 나눌 수 있다. 여기서는 그 일부만 살펴보자.


✅ 세션 쿠키 (Session Cookie)

  • Expires 또는 Max-Age 속성이 없는 쿠키
  • 브라우저 종료 시 자동 삭제
  • 브라우저 메모리에 저장됨 (정확히는 세션 스토리지 쿠키 컨테이너)
  • 일시적인 상태 유지에 사용 (ex. 로그인 유지, 폼 데이터)

✅ 영속 쿠키 (Persistent Cookie)

  • Expires 또는 Max-Age 속성이 설정된 쿠키
  • 브라우저를 껐다 켜도 그대로 복원되어 사용 가능
  • 브라우저의 로컬 디스크에 저장됨 (운영체제의 사용자 데이터 영역에 있는 쿠키 DB(SQLite) 또는 텍스트 파일 형식)
  • 재방문 시 자동 로그인, 환경 설정 등에 사용

✅ Third-Party 쿠키 (제3자 쿠키)

  • 현재 사용자가 방문 중인 도메인(origin)이 아닌 다른 도메인에서 설정되거나 전송되는 쿠키
  • 반대로, 현재 도메인과 동일한 쿠키는 First-Party 쿠키
  • 사용자 추적, 타겟 광고, 리타게팅용으로 사용
  • 사용자의 의도와 상관없이 다수 사이트에서 동일한 쿠키가 수집됨
  • 크로스 사이트 트래킹으로 인해 익명성이 침해
  • 최근 브라우저들이 점점 더 강하게 차단 중

 

 


🔷 쿠키의 주요 속성

속성 설명 예시
Name=Value 쿠키 이름과 값 (필수) sessionId=abc123
Expires 쿠키의 만료 시간 Expires=Wed, 10 Apr 2025 23:59:59 GMT (UTC 시간 문자열)
Max-Age 쿠키의 유효 시간 (Expires보다 우선) Max-Age=3600 (초 단위)
Domain 쿠키가 유효한 도메인 Domain=example.com
Path 쿠키가 유효한 경로 Path=/
Secure HTTPS 연결에서만 전송됨 Secure
HttpOnly 자바스크립트로 접근 불가 HttpOnly
SameSite 교차 요청 시 쿠키 전송 여부 제어 SameSite=Lax

 

 

✅ 1. Name=Value

  • 쿠키의 고유한 이름과 값 (Key-Value 구조)
  • 필수 속성

 

📌 예시

Set-Cookie: sessionId=abc123

 


✅ 2. Expires

  • 쿠키의 만료 시간(UTC 시간 문자열)을 지정
  • 만료 시간을 지정하면 브라우저를 닫아도 쿠키가 유지됨 → "영속 쿠키"
  • 지정된 시점 이후에는 브라우저가 쿠키를 자동 삭제
  • 반대로 만료 시간을 지정하지 않으면, 브라우저 종료 시점까지만 유지됨 → "세션 쿠키"

 

📌 예시

Set-Cookie: sessionId=abc123; Expires=Wed, 10 Apr 2025 23:59:59 GMT

 


✅ 3. Max-Age

  • 쿠키의 유효 시간(초 단위)를 지정
  • 0이면 즉시 삭제
  • -1은 브라우저 세션 종료 시 삭제 (세션 쿠키로 처리)

 

📌 예시

Set-Cookie: token=xyz; Max-Age=3600

 

비교: Max-Age가 있으면 Expires보다 우선됨

 


✅ 4. Domain

  • 쿠키를 전송할 도메인의 범위를 지정
  • 도메인을 지정하면 해당 도메인 뿐만 아니라, 서브도메인도 포함!
  • 반대로 도메인을 지정하지 않으면, 현재 요청 도메인에만 전송

 

📌 예시

Set-Cookie: uid=123; Domain=example.com

example.com, shop.example.com 모두 전송됨

 

❌ Domain=.com 같은 상위 도메인은 보안상 설정 불가

 


✅ 5. Path

  • 쿠키가 전송될 URI 경로 범위를 제한
  • 경로를 지정하면 해당 경로를 포함한 하위 경로 모두 전송!
  • 반대로 경로를 지정하지 않으면, 해당 쿠키가 설정된 요청 경로에만 전송
  • 일반적으로는 /(루트)로 지정

 

📌 예시

Set-Cookie: token=abc; Path=/api

 

/api, /api/users, /api/products 모두 전송됨

 


✅ 6. Secure

  • 쿠키를 HTTPS 연결에서만 전송하도록 강제
  • 암호화되지 않은 HTTP에서는 전송 안 함
  • 중간자 공격(MITM) 방지

 

📌 예시

Set-Cookie: auth=token; Secure
SameSite=None과 함께 사용 시 Secure 필수

 


✅ 7. HttpOnly

  • 쿠키를 자바스크립트에서 접근하지 못하도록 제한 (document.cookie로 접근 불가)
  • XSS (Cross-Site Scripting) 공격 방지

 

📌 예시

Set-Cookie: session=xyz; HttpOnly

 


✅ 8. SameSite

  • 쿠키가 Same-Site 요청에만 전송될지, 혹은 Cross-Site 요청에도 허용될지 결정
  • CSRF (Cross-Site Request Forgery) 공격 방지
옵션 설명 Cross-Site 전송 여부 CSRF 방어
Strict 완전 동일한 사이트에서만 쿠키 전송 ❌ 차단 ✅ 매우 강력
Lax 안전한 메서드(GET 등)에서는 전송 ✅ 일부 허용 일반적 방어
None 모든 요청에 전송 (3rd-party 포함) ✅ 완전 허용 (단, Secure 필요) 방어 안됨

 

📌 SameSite=Strict

  • 완전히 동일한 출처(origin) 에서만 요청 시 쿠키 전송
  • 링크 클릭, 폼 제출, 이미지 요청 등도 포함해 차단
  • 가장 강력한 CSRF 방어
  • 사용성 저하 있음 (예: 로그인 후 리디렉션 등)

 

📌 SameSite=Lax (브라우저 기본값)

  • "안전한 메서드" (GET, HEAD, OPTIONS, TRACE) 요청에는 쿠키 허용
  • 사용자가 링크 클릭, URL 직접 입력, GET 폼 제출 시는 허용
  • POST, PUT, PATCH, DELETE 같은 상태 변경 요청은 차단
  • 기본적인 CSRF 방어
  • UX와 보안 간 균형

 

📌 SameSite=None

  • Cross-Site 요청도 모두 허용
  • 단, 반드시 Secure와 함께 사용 ⚠️ (SameSite=None인데 Secure가 없으면 → 브라우저가 무시함)
  • 사용 목적
    • 3rd-party 쿠키 사용 (예: OAuth 로그인, 제휴 사이트 간 인증 공유)
    • iframe, 이미지 요청, 외부 API 등에서 필요

 

 동작 예시 비교

요청 유형 설명 Strict Lax None
브라우저 GET 직접 입력 동일 사이트
링크 클릭 (GET) Cross-Site
이미지 요청 (GET) Cross-Site
JS AJAX (POST) Cross-Site
CSRF 공격 요청 (POST) Cross-Site ✅ (위험)

 

 

✅ 권장 실무 정책

  • 인증용 쿠키: HttpOnly, Secure, SameSite=Lax 이상
  • 제휴 인증 등 교차 도메인 필요 시만 SameSite=None; Secure
  • CSRF 토큰: 추가적인 대비책 → 쿠키가 존재해도 폼 요청 내 숨은 토큰으로 서버가 요청 유효성 확인

 

 


🔷 쿠키 속성 종합 예시

Set-Cookie: sessionId=abc123;
            Domain=example.com;
            Path=/;            
            Expires=Wed, 10 Apr 2025 23:59:59 GMT;
            Max-Age=3600;
            Secure;
            HttpOnly;
            SameSite=Lax
  • 쿠키 이름은 sessionId, 값은 abc123
  • example.com 도메인 및 서브 도메인에만 전송
  • 모든 경로에 전송
  • Expires를 지정했지만, Max-Age가 있으므로 해당 쿠키는 3600초 뒤 삭제됨
  • HTTPS에서만 전송
  • 자바스크립트 접근 불가
  • "안전한" 요청 메서드(GET 등)에만 포함됨

 

 


✅ 쿠키의 장점


1️⃣ 상태 유지 가능 (Stateless한 HTTP의 한계 극복)

  • 기본적으로 HTTP는 Stateless(무상태) 프로토콜이므로, 요청 간에 사용자의 상태가 유지되지 않음
  • 쿠키를 사용하면 세션 정보(로그인 상태, 장바구니, 최근 본 상품 등)를 유지할 수 있음

2️⃣ 서버 대신 클라이언트에서 저장 및 관리 가능

  • 쿠키는 서버가 아닌 클라이언트(브라우저)에 저장되므로, 서버 측 부담을 줄일 수 있음
  • 사용자의 설정(다크 모드, 언어 설정 등)을 쿠키에 저장하여 서버 부하 없이 유지 가능

3️⃣ 자동으로 서버에 전송

  • HTTP 요청 시 자동으로 쿠키가 포함되므로, 별도의 클라이언트 작업 없이 상태를 유지할 수 있음
  • 예를 들어, 인증 정보를 쿠키에 저장하면 로그인된 상태를 자동으로 유지할 수 있음

 

 


쿠키의 단점


1️⃣ 보안 취약점 존재 (XSS, CSRF, MITM 공격 가능성)

  • 쿠키는 클라이언트에 저장되므로, 악성 자바스크립트가 접근할 경우 탈취될 위험이 있음 (XSS 공격)
  • 공격자가 사용자의 쿠키를 조작하면 세션을 가로챌 수 있음 (세션 하이재킹)
  • 악성 사이트에서 사용자의 쿠키를 이용해 요청을 보낼 가능성이 있음 (CSRF 공격)

 

🔴 해결책

 HttpOnly 설정 → 자바스크립트 접근 차단 (XSS 방지)

 SameSite 설정 → CSRF 공격 방지

 Secure 설정 → HTTPS를 통한 전송만 허용

 


2️⃣ 클라이언트에서 조작 가능 (신뢰할 수 없음)

  • 사용자가 브라우저 개발자 도구를 통해 쿠키 값을 수정할 수 있음
  • 즉, 쿠키에 저장된 데이터는 무결성이 보장되지 않으며 변조될 가능성이 있음

 

🔴 해결책

 중요한 데이터(예: 사용자 권한, 금액 등)서버 측에서 관리

 JWT(JSON Web Token) 또는 세션 저장소 사용

 


3️⃣ 네트워크 트래픽 증가

  • 쿠키는 요청이 발생할 때마다 서버로 자동 전송되므로, 트래픽이 증가할 수 있음
  • 특히, 쿠키 크기가 크거나, 모든 요청에서 필요하지 않은 데이터를 포함할 경우 불필요한 네트워크 오버헤드가 발생

 

🔴 해결책

 쿠키 크기를 최소화

 필요한 경로(Path)에만 쿠키를 적용

'HTTP' 카테고리의 다른 글

[HTTP] HTTP 캐시  (0) 2025.04.08
[HTTP] HTTP 헤더에 따른 4가지 전송 방식  (0) 2025.04.07
[HTTP] HTTP 헤더  (0) 2025.04.07
[HTTP] 클라이언트가 서버로 데이터를 전송하는 방법  (0) 2025.04.06
[HTTP] HTTP 메서드  (0) 2025.04.06