SOP, CORS를 공부하면서 어떤 개념인지도 대충 알 것 같은데,
"그래서 이게 왜 필요해? 보안적으로 무슨 의미가 있어??"라는 의문이 들었다.
이 포스팅에서는 그 내용에 대해 정리한다.
기본 개념은 아래 링크를 참조하면 이해가 잘 될 것이다.(정말 좋은 글!)
https://evan-moon.github.io/2020/05/21/about-cors/
https://802.11ac.net/2018/12/16/cors/
공격자는 자신의 사이트에 (혹은 취약점이 존재하는 사이트에) 악성 스크립트를 심어놓을 수 있다.
피해자는 해당 사이트를 정상적으로 이용하는 평범한 사람이다.
피해자가 해당 사이트를 이용하게 되면서, 공격자가 심어놓은 악성 스크립트가 동작하게 된다.
예를 들면, 아래와 같은 XSS 공격이 가능하다.
<script>
fetch('http://google.com').then(/**/) // 이후 공격자에게 전송
</script>
이 공격을 통해 공격자는 피해자가 'google.com'에 접속한 화면을 볼 수 있을 뿐만 아니라,
(가능하다면) 쿠키 값을 가져와 세션을 탈취할 수도 있을 것이다.
위와 같은 공격을 막기 위해 등장한 것이 SOP(Same-Origin Policy)이다.
말 그래도 같은 출처 정책
이라고 이해하면 되는데,
출처
라는 말은 scheme, host, port 까지를 의미한다.
쉽게 말해서 https://velog.io/write?id=something
이라는 URL이 있다면
https://velog.io/
까지만 검사한다는 뜻이다.
SOP가 적용되면서 위와 같은 fetch는 '다른 출처'에서 데이터를 받아오기 때문에 차단된다.
이 때, 차단하는 주체는 클라이언트(피해자)의 브라우저이다.
클라이언트와 서버가 정상적으로 통신은 완료하지만(code: 200), 브라우저가 클라이언트의 javascript에게 fetch의 결과값을 넘겨주지 않는 방식으로 동작한다. 위 시나리오에서도 피해자의 브라우저에서 fetch는 정상적으로 동작하지만, 그 결과값을 javascript로 넘겨받을 수 없기 때문에 .then 이후의 스크립트가 동작하지 않는다.
한편, SOP는 개발자들에게 엄청난 스트레스를 가져오게 되는데 그 이유는
1. 개발할 때 '다른 출처'의 API 서버를 두는 경우가 많기 때문
2. 개발할 때 '다른 출처'의 외부 리소스를 가져다 쓰는 경우가 많기 때문 이다.
SOP의 이러한 불편함을 해소하기 위해 등장한 것이 CORS(Cross-Origin Resource Sharing)이다.
"CORS를 지키면, '다른 출처'에서도 데이터를 불러올 수 있게 해줄게!"
라고 생각하면 편하다.
실제로 서버에 Access-Control-Allow-Origin
헤더를 설정해주면 CORS를 적용할 수 있고, SOP를 우회할 수 있다.
SOP와 CORS는 클라이언트 보안을 위해 등장한 개념인데, CORS를 구현하기 위해서는 서버에 헤더를 추가해주어야 한다.
그런데 왜 이런 식으로 만들었을까?
일반 서버와 (널리 쓰이는) API 서버의 구별을 하기 위해서라고 생각한다.
목적에 따라 클라이언트 사이드의 보안 수준을 달리하는 것이다.
API 서버들은 SOP나 CORS에 관계 없이 접근이 가능해야 하고, 사용자의 쿠키 등 중요한 데이터를 보관하지 않는다.
이런 경우에는 Access-Control-Allow-Origin: *
와 같은 헤더를 적용하여 클라이언트 사이드에서 낮은 수준의 보안을 유지해도 괜찮다.
일반 서버들은 자신의 사이트를 이용하는 사용자의 정보가 중요하기 때문에 Access-Control-Allow-Origin
헤더를 자신의 사이트로 한정하는 등, 엄격한 기준을 적용하는 보안이 필요하다. 그렇게 했을 때에 본인의 사이트에 이득이 되기 때문이다.