사이트 간 요청 위조

Cross-site request forgery

다른 사이트가 로그인 쿠키를 악용해 만든 상태 변경 요청을 가려냅니다.

···
html
<div class="sd"><div class="sd-head"><strong>CSRF</strong><span id="state">live check</span></div><div class="sd-stage"><div class="tile" id="origin">other site</div><div class="arrow">→</div><div class="tile mono" id="cookie">cookie: yes</div><div class="arrow">→</div><div class="gate" id="gate">TOKEN<br>CHECK</div></div><div class="sd-foot"><span id="caption">checking boundary</span><span>tap to step</span></div></div>
css
.sd{box-sizing:border-box;width:min(94vw,700px);height:min(86vh,318px);padding:clamp(9px,2.3vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);display:flex;flex-direction:column;gap:clamp(6px,1.8vmin,12px);font:600 clamp(12px,2.6vmin,16px)/1.25 var(--font-sans, sans-serif)}.sd *{box-sizing:border-box}.sd-head,.sd-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:1.25em}.sd-head strong{color:var(--accent);letter-spacing:.06em}.sd-head span,.sd-foot{color:var(--muted)}.sd-foot{font-size:clamp(12px,2.4vmin,14px)}.sd-stage{position:relative;flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:clamp(6px,2vmin,18px);overflow:hidden}.sd .mono{font-family:ui-monospace,monospace}.sd .tile{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(5px,1.5vmin,10px);text-align:center}.sd .good{color:var(--accent);border-color:var(--accent)}.sd .bad{color:var(--accent-3);border-color:var(--accent-3)}.sd .arrow{color:var(--muted);font-size:clamp(15px,4vmin,28px)}.sd .active{background:color-mix(in srgb,var(--accent) 16%,var(--surface));border-color:var(--accent)}.sd .blocked{background:color-mix(in srgb,var(--accent-3) 13%,var(--surface));border-color:var(--accent-3)}.sd-stage .tile{min-width:21%}.gate{border:2px solid var(--accent-3);border-radius:8px;padding:clamp(5px,2vmin,13px);text-align:center;color:var(--accent-3);transition:all .2s}.gate.pass{border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,var(--surface))}
js
let n=0;function advance(){n=1-n;document.getElementById('origin').textContent=n?'same site':'other site';document.getElementById('gate').classList.toggle('pass',!!n);document.getElementById('state').textContent=n?'token valid':'token missing';document.getElementById('caption').textContent=n?'request accepted':'cookie alone is insufficient'}advance();setInterval(advance,900);
document.querySelector('.sd').addEventListener('pointerdown',advance);

CSRF는 사용자의 브라우저가 로그인 쿠키를 자동으로 붙이는 점을 악용합니다. 공격 사이트가 송금이나 설정 변경 요청을 만들면, 서버가 요청 출처를 확인하지 않을 경우 사용자 행동으로 오인할 수 있습니다.

데모에서는 쿠키가 있어도 올바른 출처와 CSRF 토큰이 없는 요청이 차단됩니다. SameSite 쿠키와 Origin 검사도 보호에 도움이 되며, 상태를 바꾸는 요청에서 검증해야 합니다.

언제 쓰나

쿠키 기반 세션에서 결제·설정 변경·삭제 같은 상태 변경 요청을 처리할 때 적용합니다.

페이지로 열기 ↗