CORS와 CSRF 정리
웹 보안에서 자주 함께 언급되는 개념이 CORS와 CSRF이다.
둘 다 “쿠키”와 “브라우저”에서 출발하지만, 막으려는 문제와 차단 지점은 완전히 다르다.
핵심부터 정리하면 다음과 같다.
CORS는 ‘응답을 읽을 수 있느냐’의 문제고,
CSRF는 ‘요청을 실행해도 되느냐’의 문제다.
CORS란?
https://www.mySite.com:443/mypage?id=1&name=honggildong
현재 위의 TEST주소를 분해하면 아래와 같다.
| protocol (scheme) | https |
| hostname | mySite.com |
| port | 443 (https 기본 포트) |
| pathname (path) | /mypage |
| search (query string) | ?id=1&name=honggildong |
| origin | protocol + "://" + hostname + ":" + port |
Origin이 다른 요청에 대해, 서버가 허용하지 않은 경우에 한해 브라우저가 응답을 JS에서 읽지 못하게 제한하는 정책이다.
CSRF란?
사용자가 이미 인증된 상태임을 악용하여, 공격자가 의도한 요청을 사용자가 모르게 서버에 전송하게 만드는 공격 기법이다.
1. CORS (Cross-Origin Resource Sharing)
CORS가 문제 되는 상황
- 사용자가 은행 사이트에 접속해 로그인에 성공한다.
- 로그인 유지용
JSESSIONID가 브라우저 쿠키에 저장된다. - 사용자가 악성 사이트에 접속한다.
- 악성 사이트의 JavaScript가 은행 API로 요청을 시도한다.
(이때 브라우저가 쿠키를 자동으로 포함한다) - 은행 서버는 정상적으로 사용자 정보를 포함한 응답을 생성한다.
- 하지만 브라우저는 다른 Origin의 JavaScript에게 해당 응답을 전달하지 않는다.

핵심 포인트
- 요청은 서버까지 정상적으로 도달한다
- 서버도 정상 응답을 생성한다
- 하지만 브라우저가 응답을 JS에게 전달하지 않는다
- 이것이 CORS의 본질이다
즉, CORS는 서버 보안이 아니라 브라우저 보안 정책이다.
2. CSRF (Cross-Site Request Forgery)
CSRF는 응답을 읽을 필요가 없다.
요청이 실행되는 것 자체가 문제인 공격이다.
CSRF 예시 1: 토큰이 없는 경우
- 사용자가 은행 사이트에 접속해 로그인을 성공한다.
- 로그인 유지용
JSESSIONID가 브라우저 쿠키에 저장된다. - 사용자가 악성 사이트에 접속한다.
- 악성 사이트의 JavaScript가 은행 API로 송금요청을 시도한다.
(응답은 중요하지 않고, 실행 자체가 목적) - 하지만 은행의 송금 API는 CSRF 토큰을 요구한다.
- 해당 요청에는 CSRF 토큰이 없기 때문에 서버에서 거부된다.
→ CSRF 공격 실패

CSRF 예시 2: 토큰이 발행된 이후에도 공격이 실패하는 이유
- 로그인 성공
- 사용자가 송금/게시글 작성 등 Form 페이지에 접속
- 서버가 CSRF 토큰을 발행
(HTML body 또는 쿠키를 통해 전달) - 악성 사이트는 “해당 페이지가 열렸다는 사실”까지만 알 수 있다.
- HTML 응답 내용에는 접근 불가능 (Same-Origin Policy)
- CSRF 토큰이 쿠키에 있더라도
- 다른 Origin의 JavaScript는 쿠키 값을 읽을 수 없다
- 토큰 값을 요청에 재사용할 수 없으므로 공격 실패
→ CSRF 공격 실패

'Java' 카테고리의 다른 글
| [Java] Spring Boot에서 Bean 등록하는 법 (0) | 2025.12.21 |
|---|---|
| [Java] 웹 서버와 WAS (0) | 2025.12.19 |
| [Java] String, StringBuffer, StringBuilder (0) | 2025.12.12 |
| [Java] Framework, Library (0) | 2025.12.11 |
| [Java] Spring의 탄생 배경 (0) | 2025.12.11 |