CORS란?
CORS란 Cross Origin Resource Sharing 의 약자로, 한국어로 교차 출처 리소스 공유라는 뜻입니다.
기본적으로 웹 브라우저는 동일 출처 정책(Same-Origin Policy)을 따르며, 이는 같은 출처에서만 리소스를 공유하도록 제한하는 보안 정책입니다.
그러나 CORS는 추가적인 HTTP 헤더를 사용하여 한 출처에서 실행 중인 웹 어플리케이션이 다른 출처의 선택한 리소스에 접근할 수 있도록 허용합니다.
Cross-Origin Resource Sharing (CORS)는 웹 페이지가 다른 도메인에서 리소스를 요청할 때, 보안상의 이유로 발생하는 제한을 완화하기 위한 정책입니다.
예를 들어, http://domain1.com에서 실행 중인 웹 페이지가 XMLHttpRequest 또는 Fetch API를 사용하여 http://domain2.com의 리소스를 요청할 수 있습니다.
이는 API 서버와 같은 다른 도메인으로 AJAX 요청을 보내는 등의 상황에서 유용합니다.
front-end 쪽의 화면과 api 서버가 같으면 same origin,
다르다면 cross origin으로, 아래 그림과 같이 표현할 수 있으며,
기본적으로 cross origin으로 통신불가하나 api 서버 변경으로 이를 가능하게 만들 수 있다로 정리할 수 있습니다.
CORS 해결방법
웹 개발을 하다보면 개발자도구에서 아래와 같이
access to xmlhttprequest at has been blocked by CORS policy no ‘access-control-allow-origin’ header is present
라는 메시지를 보실 수 있는데요,
이를 해결하려면 서버를 개발할때, 다른 도메인에서도 호출가능하도록 허용해주도록 개발해야 합니다.
정확히는, 서버쪽에서 http response header에 Access-Control-Allow-Origin 값을 변경해주어야 합니다.
어디든 상관없이 적용해주려면 http response를 하기위해 “access-control-allow-origin: *”로 명시해주어야 하며,
특정 도메인에서만 적용하려면 “access-control-allow-origin: http://domain-a.com“ 과 같이 명시해주면 됩니다.
주요 웹 프레임워크 별 CORS 해결하기 위한 예제코드는 아래와 같습니다.
아래 모든 예제는 모든 origin에 대해 resource를 허용하겠다는 것으로 가정합니다.
CORS 해결방법 : nodejs
1 | const http = require('http'); |
CORS 해결방법 : flask
1 | from flask import Flask |
CORS 해결방법 : fastapi
1 | from fastapi import FastAPI |
CORS 해결방법 : spring boot
WebConfig.class 파일을 만들고, addCorsMappings메소드를 아래와 같이 구현합니다.
1 |
|
SOP (Same Origin Policy) 가 브라우저 기본적인 정책인 이유
SOP를 왜 해야하는지, CORS 에러는 왜 개발자들을 괴롭히는지 알아보겠습니다.
만일 SOP가 아닐경우, CSRF와 같이 보안 사고가 발생할 수 있기 때문입니다.
어떤 악의적인 공격이 발생될 수 있는지 알아봅시다.
- 먼저, 아래와 같은 상황을 가정합니다.
- bank.com : 정상적인 서비스 (송금가능한 사이트)
- evil.com : 악의적인 사이트
evil.com 은 아래와 같이 구성되어있다고 합시다.1
2
3
4
5<form method="post" action="http://bank.com/trasfer">
<input type="hidden" name="to" value="evil">
<input type="hidden" name="ammount" value="100">
<input type="submit" value="주식종목 추천드립니다">
</form>
- 아래와 같은 순서로,
bank.com 에 로그인을 한 상태에서 evil.com에서 악의적으로 bank.com 으로 request를 날릴 수 있습니다.
(사용자가 인지하지 못한 채로, 돈이 송금될 수 있는 사례입니다)
hide footbox
user -> bank.com : 로그인
bank.com -> user : 로그인정보가 담긴 session cookie 리턴
user -> evil.com : session cookie가 존재하는 상태로 사이트 접근
user -> evil.com : 사용자가 button 클릭
user -> bank.com : 로그인된 상태에서(session cookie 포함된 상태에서) evil로 $100 송금
footer devscb.com
@enduml
</div>
## 총평
개발할때 CORS가 뭔지 잘 모르고 이 문제를 해결하기 위해서 단순히 아래와 같이 header에 모든 도메인 허용하신 분들이 많을 것 같습니다.
Access-Control-Allow-Origin : *
그러나 이렇게 설정하면 얼마든지 보안사고가 일어날 수 있으니, 유의하셔야 겠습니다.
무작정 웹에 나와있는 코드만 보고 에러메시지만 없애려고만 하지 마시고,
이 개념을 잘 이해하셔서 보안사고가 일어나지 않도록 유의하시길 바랍니다.
#CORS, #SOP