쿠키
쿠키는 서버에서 설정되며 HTTP 요청과 함께 자동으로 전송된다.
- 기본적으로 JavaScript로 접근 가능하기 때문에 XSS 공격 시 탈취될 수 있음
- 단,
HttpOnly플래그를 설정하면 JavaScript에서 쿠키에 접근하는 것 자체가 차단되어 XSS를 통한 탈취를 방어할 수 있음 Secure플래그를 추가하면 HTTPS 연결에서만 쿠키가 전송되어 중간자 공격도 방어 가능
- 쿠키는 요청마다 자동 전송되기 때문에 공격자가 피해자의 브라우저로 의도치 않은 요청을 보낼 수 있음
- 대응 방법:
SameSite=Strict또는SameSite=Lax설정으로 타 사이트에서의 요청 시 쿠키 전송을 제한- CSRF 토큰을 함께 사용하여 서버에서 요청의 진위를 검증
로컬 스토리지
로컬 스토리지는 JavaScript를 통해서만 접근 가능하며, HTTP 요청과 함께 자동으로 전송되지 않는다.
- XSS 공격이 발생하면 로컬 스토리지에 저장된 모든 데이터가 노출됨
- 쿠키와 달리
HttpOnly와 같은 JavaScript 접근 차단 수단이 존재하지 않음 - 즉, XSS가 발생한 순간 방어 수단이 없음
- 자동 전송되지 않기 때문에 CSRF 공격에는 상대적으로 안전함
- 단, API 요청 시 직접 토큰을 담아 보내는 구현이 필요함
비교
| 쿠키 | 로컬 스토리지 | |
|---|---|---|
| 자동 전송 | O (HTTP 요청마다) | X |
| CSRF 취약성 | 취약 (SameSite로 방어 가능) | 안전 |
| XSS 취약성 | 취약 (HttpOnly로 방어 가능) | 취약 (방어 수단 없음) |
| 서버 접근 | O | X |
| 만료 설정 | O | X (직접 구현 필요) |
권장
인증 토큰(세션, JWT 등)은 쿠키에 저장하는 것이 권장된다.
로컬 스토리지는 XSS에 대한 방어 수단이 전혀 없기 때문에, 민감한 정보를 저장하기에는 적합하지 않다. 반면 쿠키는 아래 플래그를 조합하면 XSS와 CSRF를 모두 방어할 수 있다.
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict
HttpOnly→ JavaScript 접근 차단 (XSS 방어)Secure→ HTTPS에서만 전송 (중간자 공격 방어)SameSite=Strict→ 타 사이트 요청 시 전송 차단 (CSRF 방어)
로컬 스토리지는 인증과 무관한 비민감성 UI 상태나 캐시 데이터 저장 용도로 사용하는 것이 적절하다.