브라우저 저장소
브라우저 저장소 간 비교
브라우저 저장소에 저장된 데이터는 브라우저 메모리에 저장된 데이터가 아니기에, 새로고침 시에도 데이터가 남아있다.
| 특징 | 로컬 스토리지 | 세션 스토리지 | 쿠키 |
|---|---|---|---|
| 데이터 저장 기간 | 영구적 (삭제 시까지) | 세션 종료 시 (브라우저 탭 닫기) | 설정된 만료 시간까지 |
| 저장 용량 | 약 5~10MB | 약 5~10MB | 약 4KB |
| 데이터 접근 | 클라이언트 측 (자바스크립트) | 클라이언트 측 (자바스크립트) | 클라이언트 및 서버 측 |
| 데이터 전송 | 전송되지 않음 | 전송되지 않음 | 매 요청마다 서버로 전송 가능 |
| 보안 | XSS에 취약 | XSS에 취약 | XSS 및 CSRF에 취약 |
| 접근 범위 | 도메인 | 도메인 (탭 격리) | 도메인 및 경로 |
| 사용 예 | 사용자 설정, 장기적인 상태 저장 | 일시적인 상태 저장, 세션 기반 데이터 | 사용자 인증, 세션 관리 |
보충 설명:
-
로컬 스토리지
- 공유 범위: 동일한 도메인(Origin) 내의 모든 탭과 창에서 데이터를 공유할 수 있다.
- 브라우저 간 공유: 다른 브라우저 간에는 공유되지 않는다.
- 사용 예: 사용자 설정, 장기적인 상태 저장 (예: 테마 설정, 사용자 선호도 등).
-
세션 스토리지
- 공유 범위: 같은 브라우저의 동일한 도메인 내의 단일 탭 또는 창에서만 데이터를 공유할 수 있다.
- 다른 탭 간 공유: 동일한 도메인이라도 다른 탭이나 창 간에는 공유되지 않는다. (단,
window.open등으로 열린 탭은 세션 스토리지를 복제하여 공유될 수 있음) - 브라우저 간 공유: 다른 브라우저 간에도 공유되지 않는다.
- 사용 예: 일시적인 상태 저장, 세션 기반 데이터 (예: 일시적인 폼 데이터, 일시적인 애플리케이션 상태).
-
쿠키
- 공유 범위: 기본적으로 동일한 도메인 내의 모든 탭과 창에서 데이터를 공유할 수 있다.
- 도메인 제어: 쿠키의
Domain속성을 설정하여 서브 도메인 간에도 데이터를 공유할 수 있다. 예를 들어,example.com에서 설정한 쿠키를sub.example.com에서도 접근 가능하게 할 수 있다. - 브라우저 간 공유: 브라우저 간에는 공유되지 않는다.
- 사용 예: 사용자 인증, 세션 관리 (예: 로그인 세션, 사용자 식별 정보).
쿠키 옵션 설명
| 옵션 | 설명 | 설정 위치 | 보안 |
|---|---|---|---|
Name | 쿠키를 식별하는 데 사용된다. 동일한 도메인 내에서 고유해야 한다. | Client, Server | - |
Value | 쿠키에 저장되는 데이터이다. 보안에 민감한 정보는 포함하지 않는 것이 좋다. | Client, Server | - |
Domain | 특정 도메인 또는 하위 도메인에서만 쿠키를 사용할 수 있게 제한한다. 예: .example.com 설정 시 모든 하위 도메인에서도 쿠키가 사용된다. | Client, Server | - |
Path | 특정 경로에서만 쿠키를 사용할 수 있게 제한한다. 예: /account 설정 시 /account와 그 하위 경로에서만 쿠키가 사용된다. | Client, Server | - |
Expires | 쿠키의 유효 기간을 설정한다. 날짜를 지정하지 않으면 세션 쿠키가 되며, 브라우저를 닫으면 삭제된다. 예: expires=Wed, 21 Oct 2021 07:28:00 GMT. | Client, Server | - |
Max-Age | Expires 대신 사용할 수 있으며, 초 단위로 유효 기간을 설정한다. 예: max-age=3600 설정 시 1시간 후에 쿠키가 만료된다. | Client, Server | - |
Secure | 이 옵션을 설정하면 쿠키가 HTTPS 연결에서만 전송된다. | Client, Server | 스니핑 공격 방지 |
SameSite | Strict, Lax, None 중 하나를 선택할 수 있다. | Client, Server | CSRF 방지 |
HttpOnly | 이 옵션을 설정하면 JavaScript(document.cookie)를 통한 쿠키 접근을 방지할 수 있다. | Server | XSS 방지 |
SameSite 옵션 값 설명:
Strict: 쿠키가 동일 사이트(Same-Site) 요청에서만 전송된다. 타 사이트에서의 모든 요청(링크 클릭 포함)에는 쿠키가 전송되지 않는다.Lax(Default): 쿠키가 동일 사이트 요청과 안전한(Safe) HTTP 메서드(GET 등)를 사용한 최상위 내비게이션(Top-level navigation, 예: 링크 클릭) 요청에서만 전송된다.fetch,XHR,iframe,img등의 크로스 사이트 요청에서는 전송되지 않는다.None: 모든 크로스 사이트 요청에서 쿠키가 전송된다. 이 옵션을 사용할 경우Secure옵션을 반드시 함께 설정해야 한다.
SameSite 이슈: 외부 사이트 유입 시 인증 쿠키 미전송 문제
문제 상황
외부 사이트(SNS, 이메일, 타 블로그 등)에 공유된 링크를 통해 서비스에 접속할 때, Next.js의 Proxy나 Middleware에서 사용자의 인증 상태를 정상적으로 식별하지 못하는 현상이 발생함.
- 증상: 로그인이 된 상태임에도 외부 링크로 접속하면 비로그인 상태로 간주되어, 권한에 따른 페이지 분기(Redirect)나 페이징 처리가 정상적으로 이루어지지 않음.
- 원인: 인증 쿠키의
SameSite속성이Strict로 설정되어 있어, 외부 사이트로부터의 유입 시 쿠키가 서버로 전송되지 않았기 때문임.
원인 분석: SameSite 속성에 따른 동작 차이
브라우저는 CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해 쿠키의 전송 범위를 SameSite 속성으로 제한한다.
-
SameSite=Strict- 쿠키를 생성한 도메인과 요청을 보내는 도메인이 정확히 일치할 때만 쿠키를 전송함.
- 외부 사이트에서 링크를 클릭하여 이동하는 크로스 사이트 내비게이션(Cross-site navigation) 시에는 GET 요청임에도 불구하고 쿠키를 전송하지 않는다.
- 이로 인해 서버(Next.js)는 요청 헤더에서 인증 쿠키를 찾을 수 없어 사용자를 비인증 상태로 판단하게 된다.
-
SameSite=Lax(현재 브라우저들의 기본값)Strict보다 완화된 정책으로, 사용자가 외부 사이트에서 링크를 클릭하여 이동하는 최상위 내비게이션(Top-level Navigation)이면서 안전한 HTTP 메서드(GET)를 사용하는 경우에 한해 쿠키 전송을 허용한다.- 단,
<iframe>,<img>태그를 통한 삽입이나 타 사이트에서의POST요청 등은 여전히 쿠키 전송을 차단하여 보안을 유지함.
해결 방법
인증 쿠키의 SameSite 설정을 Strict에서 Lax로 변경하여 외부 유입 시에도 인증 상태를 유지할 수 있도록 수정함.
결과
- 외부 링크를 통해 접속하더라도 브라우저가 인증 쿠키를 서버로 전달하게 되어, 서버 측(Proxy/Middleware)에서 정상적으로 권한을 확인하고 의도한 페이징 처리를 수행할 수 있게 됨.
- 사용자 편의성(로그인 유지)과 보안(CSRF 방어) 사이의 적절한 균형을 확보함.