CSRF: SameSite 쿠키와 토큰
Cross-Site Request Forgery가 쿠키를 악용하는 방식을 이해하고, SameSite=Strict/Lax로 이를 방지하며, 추가 보호를 위해 동기화 토큰을 추가합니다.
CSRF: SameSite 쿠키와 토큰은(는) CoddyKit의 무료 Frontend Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Frontend Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Frontend Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
CSRF란 무엇입니까?
사이트 간 요청 위조: 공격자가 인증된 사용자의 브라우저를 속여 사용자의 사이트에 요청을 보내게 하는 공격입니다. 브라우저는 사용자의 쿠키를 요청에 자동으로 첨부하므로 서버는 이를 사용자가 직접 보낸 정상적인 요청으로 판단합니다.
전형적인 CSRF 공격
사용자가 bank.com에 로그인한 상태입니다. 사용자가 evil.com을 방문합니다. evil.com은 공격자의 계좌 번호를 포함한 숨겨진 양식을 bank.com/transfer로 제출합니다. 브라우저는 bank.com의 세션 쿠키를 자동으로 전송합니다. 서버는 돈을 이체합니다.
신뢰 문제
브라우저가 출처가 다른 요청에도 쿠키를 자동으로 포함하기 때문에 CSRF가 작동합니다. 추가적인 보호 장치가 없으면 서버는 요청이 악성 사이트에서 왔다는 사실을 구분할 수 없습니다.
SameSite 쿠키 — 현대적인 해결책
SameSite 쿠키 속성은 출처가 다른 요청에 쿠키를 전송할 시점을 제어합니다. Strict: 출처가 다른 요청에는 절대 전송하지 않습니다. Lax(Chrome의 기본값): 최상위 수준의 GET 탐색에서만 전송합니다. None: 항상 전송합니다(Secure도 함께 설정해야 합니다).
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=LaxSameSite=Lax 기본값
Chrome은 SameSite를 지정하지 않은 모든 쿠키를 Lax로 설정합니다. 따라서 대부분의 CSRF가 차단되지만, 그래도 명시적으로 설정하는 것이 좋습니다.
최대 보안을 위한 SameSite=Strict
가장 민감한 쿠키(관리자 세션, 은행 거래)에는 Strict를 사용하십시오. 단점은 다른 사이트의 링크를 통해 들어온 사용자가 로그아웃된 것처럼 보인다는 점입니다.
CSRF 토큰(동기화 패턴)
오래된 브라우저를 지원하거나 보안을 강화하려면 CSRF 토큰을 사용하십시오. 서버가 무작위 토큰을 생성하여 페이지에 삽입하고, 상태를 변경하는 모든 요청에 토큰을 포함하도록 요구합니다.
// Server embeds token in HTML or sets it as a non-HttpOnly cookie:
<meta name="csrf-token" content="a1b2c3...">
// Client reads token and sends in header:
const token = document.querySelector('meta[name=csrf-token]').content;
fetch('/transfer', {
method: 'POST',
headers: { 'X-CSRF-Token': token },
body: JSON.stringify({ amount: 100 })
});
// Server verifies the X-CSRF-Token header matches the user's session이중 제출 쿠키
서버가 CSRF 쿠키를 설정합니다(JS가 읽을 수 있도록 HttpOnly가 아님). 클라이언트는 쿠키를 읽어 그 값을 헤더로 전송합니다. 서버는 쿠키와 헤더의 값이 일치하는지 확인합니다. 공격자는 출처가 다른 사이트에서 쿠키를 읽을 수 없으므로 헤더를 재현할 수 없습니다.
작동하는 이유
공격자의 evil.com은 bank.com의 쿠키를 읽을 수 없습니다(동일 출처 정책). 따라서 X-CSRF-Token 헤더를 설정할 수 없습니다. 요청은 서버의 토큰 검사를 통과하지 못합니다.
Bearer 토큰을 사용하는 SPA의 CSRF
메모리에 저장된 Authorization: Bearer <jwt>로 인증하는 경우(쿠키가 아님) CSRF가 적용되지 않습니다. 브라우저는 헤더를 자동으로 전송하지 않기 때문입니다. 대신 JS에서 접근할 수 있는 토큰을 탈취할 수 있으므로 XSS에는 더 취약해진다는 trade-off가 있습니다.
사용자 지정 헤더 트릭
사용자 지정 헤더가 포함된 JSON만 허용하는 API(예: X-Requested-With)의 경우 브라우저가 사전 요청인 OPTIONS 요청을 전송하며, 사전 요청에는 쿠키를 포함하지 않습니다. 따라서 간단한 양식 기반 CSRF를 사실상 차단합니다.
멱등 엔드포인트와 변경 엔드포인트
CSRF는 주로 상태를 변경하는 요청(POST, PUT, DELETE)에 영향을 줍니다. GET 엔드포인트는 부작용 없이 여러 번 수행해도 결과가 같도록 멱등적으로 설계해야 하므로, 위조된 GET으로는 피해를 줄 수 없어야 합니다.
빠른 확인
최신 브라우저에서 기본적으로 출처가 다른 대부분의 요청에 쿠키가 전송되지 않도록 하는 SameSite 쿠키 값은 무엇입니까?
복습: CSRF 방지
세션 쿠키에 SameSite=Lax(또는 Strict)를 설정하여 대부분의 CSRF를 차단하십시오. HttpOnly와 Secure도 추가하십시오. 보안을 강화하려면 CSRF 토큰(동기화 토큰 또는 이중 제출 쿠키)을 사용하십시오. 헤더의 Bearer 토큰은 CSRF를 방지하지만 XSS 위험을 높입니다. 사용자 지정 헤더 트릭은 사전 요청을 강제합니다. GET은 멱등적으로 만드십시오.
자주 묻는 질문
“CSRF: SameSite 쿠키와 토큰” 강의는 무료인가요?
네 — “CSRF: SameSite 쿠키와 토큰” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Frontend Academy 강의 전체를 잠금 해제할 수 있습니다. Frontend Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“CSRF: SameSite 쿠키와 토큰”에서 뭘 배우나요?
Cross-Site Request Forgery가 쿠키를 악용하는 방식을 이해하고, SameSite=Strict/Lax로 이를 방지하며, 추가 보호를 위해 동기화 토큰을 추가합니다. 브라우저에서 직접 실행하는 실습 코드로 Frontend Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Frontend Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Frontend Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“CSRF: SameSite 쿠키와 토큰” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Frontend Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Frontend Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- XSS 방지: 출력 인코딩과 CSP
- CSRF: SameSite 쿠키와 토큰
- Content Security Policy: nonce와 해시
- 프런트엔드에서 OAuth 흐름 구현