프론트엔드 개발을 하다 보면 항상 마주치는 것 중 하나가 브라우저 스토리지의 사용이다. 잘못 사용하면 보안 이슈가 생기거나 고객에게 불편을 줄 수 있다. 그래서 각 스토리지의 기본적인 특성을 정리해 본다.
4개의 브라우저 스토리지의 차이와 특징
1. 데이터 라이프 사이클
| 스토리지 | 보존 기간 | 라이프 사이클 |
| localStorage | 반영구적 | 사용자가 수동으로 삭제할 때까지(또는 코드로 삭제) |
| sessionStorage | 페이지 세션 중 | 브라우저 탭/창을 닫으면 사라짐 |
| Cookie | 설정에 따라 가변 | 만료일 설정 가능(Max-Age, Expires 속성) |
| IndexedDB | 반영구적 | 사용자가 수동으로 삭제할 때 없어짐 |
2. 용량 정책
| 스토리지 | 사이즈 상한 | 용도 |
| Cookie | 약 4KB(도메인당) | 작은 식별자, 토큰 |
| localStorage | 5 ~ 10MB | 설정 정보, 경량 데이터 |
| sessionStorage | 5 ~ 10MB | 임시 경량 데이터 |
| IndexedDB | 사용 가능한 디스크 공간에 따라 다름(일반적으로 수백MB 이상) | 대용량 데이터, 오프라인 대응 |
스펙 참조 사이트에 정책들이 기술되어 있으니 스펙 사이트를 먼저 보길 권한다.
3. 보안 정책
각 스토리지별로 XSS 취약점은 아래와 같다.
| 스토리지 | JavaScript 액세스 | XSS 공격의 위험 |
| localStorage | 가능 | 높 음 (훔칠 가능성) |
| sessionStorage | 가능 | 높음 (훔칠 가능성) |
| Cookie(HttpOnly 없음) | 가능 | 높음 (훔칠 가능성) |
| Cookie(HttpOnly) | 불가능 | 낮음 (보호됨) |
| IndexedDB | 가능 | 높음 (훔칠 가능성) |
인증 토큰과 같은 중요한 정보는 HttpOnly가 있는 쿠키에 저장하는 것이 가장 안전하다. localStorage나 sessionStorage에 저장하면 XSS 공격으로 도난당할 수 있다.
CSRF(Cross-Site Request Forgery) 공격은 사용자가 의도하지 않은 요청을 다른 사이트에서 보내는 공격을 말한다. 이것은 SameSite 속성으로 방어가 가능하다.
| SameSite 값 | 동작 | 용도 |
| Strict | 다른 사이트의 요청으로는 전송하지 않음 | 가장 안전함(인증 쿠키 권장) |
| Lax | 최상위 네비게이션(GET 요청)만 전송 | 일반 용도(기본값) |
| None | 모든 요청에 보내기(Secure 속성 필요) | 크로스 사이트에서 필요한 경우에 |
4. 성능 (속도 및 효율)
| 스토리지 | 액세스 속도 | 서버 통신 | 특징 |
| localStorage | 동기화(블로킹) | 없음 | 작은 데이터라면 고속 |
| sessionStorage | 동기화(블로킹) | 없음 | localStorage와 동등 |
| Cookie | 동기화(블로킹) | 예(자동 전송) | HTTP 요청마다 전송되므로 크기가 크면 느림 |
| IndexedDB | 비동기(논블로킹) | 없음 | 대용량 데이터에서도 UI를 차단하지 않음 |

