[1] 사용자가 은행사이트에 로그인
[2] 서버가 세션을 생성하고 세션ID를 발급
[3] 브라우저에는 해당 쿠키가 저장됨. (이후 그 은행사이트 들어갈 때 자동으로 쿠키를 첨부함)
[4] 사용자가 어쩌다가 공격자가 만들어둔 악성 사이트에 접속 → 이 사이트에는 “사용자의 계좌에서 100만원을 송금하는” 악성요청코드가 포함되어있음.
[5] 스크립트로 해당 요청코드를 실행시킴
[6] 브라우저는 동일하게 은행사이트로의 요청이므로 쿠키를 자동으로 첨부하여 요청을 보낸다.
[7] 은행서버는 “아 이거 ~~맞네 “확인하고 100만원을 이체함.


→ 쿠키와 세션이다.
# 서버가 로그인된 세션을 abc123이라는 세션아이디로 매핑해뒀고, 그걸 가지고있음.
Cookie: session=abc123
→ 사용자의 인증 상태를 이용해 의도하지 않은 요청을 보내게만드는 공격이다.
→ CSRF-token 을 사용하여 CSRF공격을 막을 수 있다.
[1] 사용자가 페이지 요청 (로그인 상태)
[2] 서버가 HTML + CSRF 토큰 같이 내려줌
<input type="hidden" name="csrf_token" value="abc123">
[3] 사용자가 폼 제출
[4] 브라우저는 요청과 함께 CSRF토큰을 서버로 전송
[5] 서버는 세션에 저장된 토큰과 요청에 포함된 토큰을 비교하여
→ 일치하면 정상 요청 처리
→ 불일치하면 요청 거부
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="x8F3k2L9">
</form>
→ “토큰은 세션과 1:1로 묶여 있어서, 남의 토큰은 쓸 수 없다”
-> Same-origin Policy
- 보통 브라우저에서 프로토콜, 도메인, 포트가 같은 출처를 갖는다.
- → URL구조에서 http부분이 프로토콜, naver.com 부분이 도메인, 8080부분이 포트이다.
예를들어 아래와 같은 경우에는 프로토콜, 도메인, 포트(디폴트값으로 들어가있음)가 전부 같음
• https://bank.com
• https://bank.com/account
하지만 아래는 다름
http://bank.com ← 프로토콜 다름
https://sub.bank.com ← 도메인 다름
https://bank.com:8080 ← 포트 다름
이런식으로 출처(프로토콜, 도메인, 포트)가 다르면 브라우저가 읽기를 제한한다.
→ 즉 토큰이 HTML에 있는데 origin이 다르기 때문에 공격자는 그걸 읽을 수없고, CSRF-token을 탈취할 수 없게 된다.
“브라우저가 쿠키를 자동 첨부하는 특성을 이용해 요청을 위조하는 공격이 CSRF이며, 이를 막기 위해 세션 기반 CSRF 토큰 검증이 필요하다.”