민감 정보를 담은 쿠키를 안전하게 보호하자!

쿠키를 안전하게 보호하기 위해 브라우저 레벨부터 서버 속성까지 다양한 방법을 학습하기

September 25, 2025

웹 브라우저에 저장되는 쿠키

로그인을 진행하면서 세션-쿠키 방식으로 구현했다.

이때 세션ID를 브라우저의 쿠키에 저장하게 되고, 브라우저와 서버는 쿠키 정보를 주고받는다.

쿠키를 저장하는 공간을 전통적으로 쿠키 통(COOKIE_JAR)라고 부른다.

브라우저는 헤더로 Set-Cookie를 받으면 COOKIE_JAR를 업데이트 해야한다.

쿠키의 특징

  • 쿠키는 브라우저의 신원으로, 같은 도메인에서 동일한 쿠키가 사용된다. 그래서 동일한 쿠키를 사용하면 동일한 사용자라고 인식한다. 이는 보안 측면에서 문제가 될 수 있다.
  • 같은 도메인 내에서는 모든 API 요청에 자동으로 세션 쿠키가 포함된다.
  • 이는 개인 프라이빗 데이터가 유출되는 것이다.
  • 공격자가 서버나 브라우저를 이용해 쿠키를 탈취할 가능성이 있다.

쿠키의 한계

이렇게 보안 기능이 따로 없는 쿠키를 위해 실무적으로 방어를 해줘야한다.

  • 브라우저 레벨: SOP(기본), CORS 정책 적절 설정
  • 쿠키 옵션: HttpOnlySecureSameSite
  • 서버 쪽: CSRF 토큰, Origin/Referer 검사, 출력 이스케이프, CSP로 XSS 차단

동일 출처 정책(SOP)

일단 감사하게도, 브라우저 레벨에서 동일 출처 정책(SOP) 기능이 장착되어있다. 서버가 Set-Cookie로 세션을 내려주면 브라우저가 동일 출처로 자동 저장·전송한다. 동일 출처란 같은 origin, 같은 호스트명, 같은 포트를 가진 웹페이지에만 전송을 허용하는 것이다.

왜 SOP가 중요하냐면

  • SOP는 다른 출처(교차 출처)의 스크립트가 해당 응답을 읽지 못하게 막는다.
  • 즉, 공격자 페이지에서 요청을 보내는 것 자체는 (브라우저가 허용하면) 가능하더라도, 응답을 읽어 처리하는 단계를 차단함으로써 데이터 유출을 막는다. 이 방법으로, 웹사이트의 프라이빗 데이터가 그 웹사이트에만 유지되고 다른 서버의 공격자에게 유출되지 않을 수 있다.

SOP가 못막는 것

SOP는 교차 출처 간의 호출을 막지만, 이런 SOP가 막지 못하는 게 있다. 폼 전송과 같은 교차 사이트 요청 위조(CSRF) 공격을 가능하게 한다. 즉, 공격자가 사용자의 브라우저로 요청을 보내게 해서 쿠키는 자동으로 포함될 수 있는 것이다.

<!-- 공격자가 만든 페이지 -->
<form action="https://bank.example/add" method="POST">
  <input name="amount" />
  <button>OK</button>
</form>

CSRF 방어

SOP의 한계로 인해 CSRF 방어(토큰, SameSite 등)가 필요하다. 폼 전송을 위한 안전한 솔루션은 SameSite 쿠키이다. 만약 서버가 자신의 쿠키를 SameSite로 설정해두면, 브라우저는 폼 전송이 교차 차이트일 때 그 쿠키를 전송하지 않는다.

  • Set-Cookie: SameSite=Lax
  • SameSite 속성은 Lax, Strict, None 3가지이다.
속성교차 사이트 GET 요청 (링크 클릭 등)교차 사이트 POST / AJAX / iframe 등동일 사이트 GET/POST 요청특징 / 주의점
Lax✅ 쿠키 전송 (탑레벨 내비게이션의 안전한 GET은 허용)❌ 쿠키 전송 안 함✅ 쿠키 전송기본값. 일반적인 사용성(링크 통한 로그인 유지)과 보안을 균형 있게 지원
Strict❌ 쿠키 전송 안 함❌ 쿠키 전송 안 함✅ 쿠키 전송가장 보안 강력. 교차 사이트에서 들어오는 모든 요청에 쿠키 차단 → 외부 리디렉션(OAuth, 결제) 깨질 수 있음
None✅ 쿠키 전송✅ 쿠키 전송✅ 쿠키 전송교차 사이트 요청에도 항상 쿠키 전송. 반드시 Secure와 함께 사용해야 하고 CSRF 방어(토큰, Origin 검증 등) 필요.
외부 연동(소셜 로그인, 결제 콜백 등) 시 사용

XSS 공격의 방어막

  • HttpOnly
    • 브라우저 내부에서만 사용 (요청 시 자동 포함)
    • JS 코드에서는 접근 불가
  • Content-Security-Policy(CSP): 콘텐츠 보안 정책

콘텐츠 보안 정책

XSS 공격의 방어막 중 하나는 Content-Security-Policy(CSP) 헤더이다. 이 헤더의 전체 사양은 복잡하지만, 가장 단순한 예시는 default-src 키워드 뒤에 공백으로 구분된 서버 목록을 설정하는 것이다.

  • Content-Security-Policy: default-src 'self'

브라우저에게 리스트된 출처를 제외한 CSS, JS, 이미지 등 어떤 리소스도 로드하지 말라고 요청한다. 만약 공격자가 페이지에 <script>를 추가했더라도 브라우저는 그 스크립트를 로드하거나 실행하지 않는다.

[로그인 요청 시 세션-쿠키 설정]