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 |