한 출처에서 실행된 스크립트가 다른 출처의 데이터를 읽지 못하게 막는 브라우저의 기본 보안 규칙. 다른 출처에 요청을 보내는 것은 대체로 허용하고, 응답을 읽는 것을 막는다.
출처(Origin)
출처는 프로토콜 + 호스트 + 포트의 조합이다. 셋 중 하나라도 다르면 다른 출처다.
비교 대상(기준: https://example.com) | 같은 출처? |
|---|---|
https://example.com/page2 | 같음(경로는 상관없음) |
http://example.com | 다름(프로토콜) |
https://api.example.com | 다름(호스트) |
https://example.com:8080 | 다름(포트) |
URL에서 호스트는 www.example.com처럼 서브도메인까지 포함한 부분이다. 같은 도메인 아래라도 www, api, admin 서브도메인(Subdomain)은 서로 다른 출처다. 참고로 "같은 사이트(same-site)"는 이보다 느슨한 개념으로, 쿠키의 SameSite가 쓰는 기준이다 → HTTP 쿠키
왜 보내기는 허용하나
웹은 원래 다른 사이트의 리소스를 가져다 쓰도록 만들어졌다. img, script, link, 폼 제출은 모두 교차 출처(Cross-Origin)일 수 있다. 그래서 "보내기는 허용, 읽기는 제한"이라는 타협을 택했다.
SOP(Same-Origin Policy)가 없다면 악성 사이트의 스크립트가 사용자가 로그인해 둔 은행 사이트에 fetch를 보내고, 쿠키가 실린 응답(계좌 정보)을 읽어 빼돌릴 수 있다. SOP는 이 읽기를 막는다. 다만 요청은 여전히 쿠키를 싣고 나가므로, "읽지 않고 실행만 시키는" 공격은 막지 못한다 → CSRF
CORS와의 관계
프런트(app.example.com)와 API(api.example.com)를 나누면 출처가 달라 SOP에 막힌다. 서버가 응답 헤더로 "이 출처는 읽어도 된다"고 허락하는 예외 장치가 CORS(Cross-Origin Resource Sharing)다. CORS는 SOP를 없애는 것이 아니라 SOP 위에 얹는 예외 규칙이다.
SOP는 브라우저가 지키는 규칙이라 서버끼리 주고받는 요청에는 없다 → 브라우저 요청과 서버 간 요청. 출처 정보는 요청의 Origin 헤더에 실린다 → Origin·Referer 헤더와 Referrer-Policy
출처: MDN — Same-origin policy · MDN — Same-origin policy: Cross-origin network access