용어 사전

CSRF(사이트 간 요청 위조)란: 로그인된 사용자가 의도하지 않은 요청을 보내게 만드는 공격

CSRF(사이트 간 요청 위조)는 로그인된 사용자의 브라우저가 의도하지 않은 요청을 보내게 만드는 공격입니다. 작동 원리와 CSRF 토큰, SameSite 쿠키, Origin 검사 등 방어법을 설명합니다.

게시 2026-06-08 업데이트 2026-10-06 5분 읽기
이 페이지에서

CSRF는 로그인된 채로 다른 사이트를 열기만 했는데 자신도 모르게 송금이나 설정 변경이 일어나는 공격입니다. 작동 원리와 확실히 막는 법을 살펴봅니다(공격 절차는 다루지 않습니다).

왜 통하는가(메커니즘)

브라우저는 어떤 사이트에 대한 요청에 그 사이트의 쿠키를 자동으로 붙입니다. 그래서 사용자가 은행에 로그인되어 있다면, 악성 페이지에서 트리거된 은행으로의 요청에도 "사용자의 쿠키"가 그대로 실립니다. 서버 입장에서는 정당한 행동과 구분할 수 없습니다.

① 사용자가 표적 사이트에 로그인됨(쿠키 보유)
↓ 다른 페이지를 연다
② 악성 페이지가 표적 사이트로 요청을 트리거
↓ 브라우저가 표적의 쿠키를 자동으로 붙임
③ 서버가 '사용자의 행동'으로 실행(송금, 설정…)
브라우저가 쿠키를 자동으로 보내기 때문에, '다른 사이트를 통한' 요청이 사용자 본인의 행동으로 통과됩니다.

XSS가 "피해자의 브라우저에서 코드를 실행"하는 것이라면, CSRF는 "피해자의 로그인 상태를 빌리는" 것입니다(→ XSS란).

방어

1

CSRF 토큰 요구

상태를 바꾸는 행동(폼 제출, API)에는 서버가 발급한, 추측 불가능한 일회성 토큰을 요구하고 토큰이 없는 요청은 거부하세요. 대부분의 프레임워크가 이를 기본 제공합니다.

2

SameSite 쿠키 설정

세션 쿠키에 SameSite=Lax(또는 Strict)를 지정해, 크로스 사이트에서 시작된 요청에 쿠키가 붙지 않게 하세요. Lax는 현대의 기본값이며 그 자체로 큰 도움이 됩니다.

3

상태 변경에 GET을 쓰지 않기

GET(조회)은 부작용이 없어야 합니다. 변경은 POST/PUT/DELETE로 만들고 토큰 검증을 거치게 하세요.

4

Origin / Referer 검사

민감한 행동에 대해서는 요청의 Origin이 내 사이트인지 확인하고, 외부 오리진은 거부하세요.

본 사이트의 견해: 대체로 '해결됨'이지만 방심은 금물

프레임워크의 CSRF 토큰과 브라우저의 SameSite=Lax 기본값이 고전적 CSRF를 크게 줄였습니다. 그래도 커스텀 API, 레거시 구성, 토큰을 건너뛴 관리자 패널에서는 여전히 발생합니다. "프레임워크에 맡긴다" 하더라도, 상태 변경 경로가 실제로 토큰 검증을 거치는지는 한 번 직접 확인하세요.

흔한 빈틈

메커니즘을 알더라도 구현은 두 곳에서 미끄러지기 쉽습니다.

  • 부작용 있는 GET: 조회용 GET이 상태를 바꾸면, 이미지 태그나 평범한 링크 하나로도 CSRF가 됩니다. 상태 변경은 POST/PUT/DELETE로 만들고 토큰 검증을 거치게 하세요.
  • 일부 경로의 토큰 검증 누락: 나중에 추가된 API와 관리자 기능은 종종 토큰을 건너뜁니다. "프레임워크에 있겠지"라고 가정하지 말고, 상태를 바꾸는 모든 경로를 한 번 정리해 점검하세요.

CSRF vs XSS vs SSRF

이름이 비슷한 세 가지는 누가 요청을 보내는지, 무엇에 기대는지로 구별할 수 있습니다.

공격요청을 보내는 주체악용되는 것주된 방어
CSRF사용자가 모르는 사이 사용자의 브라우저브라우저가 쿠키를 자동으로 붙이는 성질CSRF 토큰, SameSite 쿠키
XSS사용자의 브라우저에서 실행되는 공격자의 스크립트페이지를 출력할 때 이스케이프 누락출력 시 이스케이프, CSP
SSRF내 서버받은 URL을 가져오는 기능목적지 허용 목록, 내부 주소 차단

CSRF와 XSS는 둘 다 사용자의 브라우저를 통해 일어납니다. 다만 페이지에 XSS가 있으면 그 안의 스크립트가 CSRF 토큰을 읽을 수 있어 CSRF 대책이 우회됩니다. CSRF 대책은 XSS가 이미 해결되었다는 전제 위에 서 있습니다.

실제 사례: 위조된 글이 본인의 글로 취급되다

2012년 요코하마시 웹사이트의 의견 접수 폼으로 초등학교를 습격하겠다는 협박 글이 올라왔습니다. 글을 보낸 것처럼 보인 PC의 주인이 체포되었지만, 나중에 오인 체포였던 것으로 밝혀졌습니다. 일본 언론 보도에 따르면 그해 12월 도쿄 경시청은 이 글이 CSRF로 전송되었다고 설명했습니다. 게시판에 올라온 링크를 연 방문자의 브라우저가 글을 제출하게 만든 것입니다.

교훈은 두 가지입니다.

  • CSRF 요청은 본인의 요청과 똑같아 보인다: 서버에 보이는 것은 사용자의 IP 주소와 쿠키뿐입니다. 로그만으로는 사용자가 보냈는지, 보내게 만들어졌는지 구별할 수 없습니다.
  • 로그인이 없는 폼도 대상이다: 그 의견 접수 폼은 로그인이 필요 없었습니다. 로그인 필요 여부와 상관없이, 남이 일으키면 곤란한 제출(게시, 신청, 신고)에는 토큰을 붙이세요.

CSRF는 지금도 흔한 약점입니다. 2025년 12월 공개된 MITRE의 "CWE Top 25"(가장 위험한 소프트웨어 약점 25개)에서 CSRF(CWE-352)는 3위였습니다.

내 사이트에서 확인하는 방법

1

세션 쿠키에 SameSite를 명시한다

브라우저 개발자 도구(Application → Cookies)나 사이트 점검으로 세션 쿠키의 SameSite 속성을 확인합니다. Chrome과 Edge는 속성이 없는 쿠키를 Lax로 취급하지만, Safari와 Firefox는 기본으로 그렇게 하지 않습니다. 브라우저 기본값에 기대지 말고 SameSite=Lax나 Strict를 직접 지정하세요.

2

CSRF 예외 설정을 점검한다

프레임워크의 CSRF 보호가 일부 경로에서 꺼져 있지 않은지 확인합니다(Django의 csrf_exempt, Laravel의 예외 목록, Rails의 skip_forgery_protection 등). 웹훅 수신처럼 끌 이유가 있는 경로는 대신 서명 검증으로 보호하세요.

3

상태를 바꾸는 GET 경로를 찾는다

라우트 목록에서 삭제, 수정, 로그아웃을 하는 GET 경로가 없는지 살펴봅니다. 있다면 POST 등으로 옮기고 토큰 검증을 거치게 하세요.

4

중요한 조작에는 확인을 하나 더 둔다

비밀번호나 이메일 주소 변경, 송금, 권한 부여에는 토큰에 더해 현재 비밀번호나 다단계 인증을 요구하세요. 요청이 위조되더라도 본인 확인에서 멈춥니다.

출처(1차 자료)

  • OWASP, "Cross-Site Request Forgery Prevention Cheat Sheet" — cheatsheetseries.owasp.org(토큰, Sec-Fetch-Site, SameSite의 한계, XSS에 의한 CSRF 대책 우회, GET으로 상태를 바꾸지 않기)
  • MITRE, "2025 CWE Top 25 Most Dangerous Software Weaknesses"(2025년 12월) — cwe.mitre.org(CWE-352가 3위)
  • web.dev, "SameSite cookies explained" — web.dev(속성이 없는 쿠키를 Lax로 취급하는 브라우저)
  • INTERNET Watch, 원격 조작 악성코드 사건 보도(2012년 12월 14일, 일본어) — internet.watch.impress.co.jp(요코하마시 게시에 CSRF가 쓰였다는 경찰 설명)
  • @IT, 사칭 악성코드와 CSRF로 인한 오인 체포 기사(2012년 11월, 일본어) — atmarkit.itmedia.co.jp
  • IPA, "안전한 웹사이트 만드는 법"(일본어) — ipa.go.jp

다음으로 읽기

분류 번호

CWE는 취약점의 원인이 되는 약점의 종류를, MITRE ATT&CK는 공격자의 기법을 분류한 번호 체계입니다. 둘 다 MITRE가 관리하며 취약점 정보와 탐지 규칙 분류에 널리 쓰입니다.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QCSRF는 XSS와 어떻게 다른가요?
A

XSS는 피해자의 브라우저에서 스크립트를 실행하고, CSRF는 피해자의 로그인 상태를 이용해 의도치 않은 요청을 보냅니다. CSRF는 스크립트를 전혀 실행하지 않아도 작동합니다 — 브라우저가 쿠키를 자동으로 보내는 것만으로 충분합니다.

QCSRF의 최우선 방어책은 무엇인가요?
A

상태를 바꾸는 요청(POST 등)에 CSRF 토큰을 요구하고, 세션 쿠키에 SameSite(Lax/Strict)를 설정하세요. 대부분의 프레임워크는 토큰을 기본 제공합니다. 그리고 상태 변경에는 절대 GET을 쓰지 마세요.

QSameSite만으로 충분한가요?
A

큰 도움이 되지만 그것만으로 완전하지는 않습니다. 구형 브라우저, 일부 내비게이션, 특정 서브도메인 구성에는 빈틈이 남습니다 — 그러니 심층 방어를 위해 CSRF 토큰과 함께 쓰세요.

Q로그인이 필요 없는 폼에도 CSRF 대책이 필요한가요?
A

필요한 경우가 있습니다. 문의 폼이나 게시 폼도 다른 사이트에서 방문자의 브라우저를 통해 제출될 수 있고, 그러면 서버에는 그 방문자의 IP 주소가 보낸 사람으로 기록됩니다. 2012년 일본에서는 요코하마시 웹사이트에 올라온 협박 글이 CSRF로 전송된 것이었고, 글을 보낸 것처럼 보인 PC의 주인이 잘못 체포되었습니다. 로그인 필요 여부와 상관없이, 남이 방문자 대신 제출하면 곤란한 폼에는 토큰을 붙이세요.

QBearer 토큰으로 인증하는 JSON API에도 CSRF 대책이 필요한가요?
A

인증에 쿠키를 쓰는지에 달려 있습니다. CSRF는 브라우저가 쿠키를 자동으로 붙이는 성질에 기댑니다. Authorization 헤더의 Bearer 토큰처럼 앱이 직접 붙이는 인증 정보만 받는 API는 다른 사이트가 브라우저에 그것을 붙이게 할 수 없으므로 일반적으로 CSRF의 대상이 되지 않습니다. 쿠키로 인증하는 API라면 토큰이나 Origin 확인이 필요합니다.

QSec-Fetch-Site란 무엇이며, CSRF를 막을 수 있나요?
A

요청이 같은 오리진·사이트(same-origin / same-site)에서 왔는지 다른 사이트(cross-site)에서 왔는지를 브라우저가 알려 주는 요청 헤더입니다. OWASP의 CSRF 가이드는 이 값을 근거로 크로스 사이트의 상태 변경 요청을 거부하는 것을 대책 중 하나로 듭니다. 구형 브라우저는 이 헤더를 보내지 않으므로 Origin 확인을 대비책으로 남겨 두세요.