2023. 8. 6. 18:00ㆍ브라우저&네트워크
처음 협업하면서 프론트와 백엔드 작업을 하면 꼭 마주치는 문제가 CORS 문제인 것 같다.
왜 발생하고 어떻게 방지할 수 있는지 확인하는 것이 목적입니다.
CORS 란?
CORS(Cross-Origin Resource Sharing)는 출처가 다른 자원들을 공유한다는 뜻이다.
한 출처에 있는 자원에서 다른 출처에 있는 자원에 접근하도록 하는 개념이다.
교차되는 출처 자원들의 공유이다. 다른 출처에 있는 자원을 요청한다고 하면, 이를 교차 출처 요청이라고 한다.
CORS 는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.
- mdn -
즉 프로토콜, 호스트, 포트 3가지가 같으면 동일 출처(Origin) 라고 한다.
다른 출처 요청일 경우, CORS 정책에 준수하여 요청해야만 정상적으로 응답을 받는다.
다른 출처 요청의 위험
img, script, frame, video, audio 등의 태그가 웹에 등장하면서 페이지 로딩 이후에 브라우저에서 이러한 하위 자원들을 가져올 수 있게 되었다.
그러므로 동일 출처, 다른 출처 모두 호출이 가능하게 되었다.
예를 들어서 script 가 심어진 bad.com 페이지를 열었다고 생각한다면, 굉장히 유용한 정보를 담고있는 사이트지만 페이지를 열면서 script 가 실행되어 은행에 delete/account 요청을 하도록 되어있다.
이러면 AJAX 호출로 은행 API 를 호출하여 나의 은행 계좌를 삭제해버리는 사고가 발생한다.
이때문에 동일 출처 정책이 등장했다.
동일 출처 정책 (same-origin policy)
동일 출처 정책은 다른 출처로부터 조회된 자원들의 읽기 접근을 막아 다른 출처 공격을 예방한다.
그러나 다른 출처에서 얻은 이미지를 담는 img 외부 주소를 담은 link 같은 여러 태그들을 허용한다.
동일 출처 정책은 다른 출처 자원을 가져오는 것을 제한적으로 허용한다.
또한 SPA 와 미디어 중심 웹 사이트 들이 더욱 늘어나고 있으므로 관련 규칙들도 계속 늘어난다.
따라서 다른 출처 리소스에 접근성을 높이기 위해서 CORS 가 등장했다.
사실 출처가 다른 두 어플리케이션이 자유로이 소통할 수 있는 환경은 위험하다.
만일 제약이 없다면 해커가 CSRF 나 XSS 등의 방법을 이용해서 우리가 만든 어플리케이션에서 해커가 심어놓은 코드가 실행하여 개인 정보를 가로챌 수 있다.
악의적인 경우를 방지하기 위해, SOP 정책으로 동일하지 않는 다른 출처의 스크립트가 실행되지 않도록 브라우저에서 사전에 방지하는 것이다.
요청 방식에 따라 다른 CORS 발생 여부
1. img, video, script, link 태그 등
기본적으로 Cross-Origin 정책을 지원한다.
- link 태그의 href 에서 다른 사이트의 .css 리소스에 접근하는 것이 가능
- img 태그의 src 에서 다른 사이트의 .png, .jpg 등의 리소스에 접근하는 것이 가능
- script 태그의 src 에서 다른 사이트의 .js 리소스에 접근하는 것이 가능 (type='module' 속성은 제외)
2. XMLHttpRequest, Fetch API 스크립트
기본적으로 Same-Origin 정책을 따른다.
- 다른 도메인의 소스에 대해 자바스크립트 ajax 요청 API 호출시
- 웹 폰트 CSS 파일 내 @font-face 에서 다른 도메인의 폰트 사용시
자바스크립트에서의 요청은 기본적으로 서로 다른 도메인에 대한 요청을 보안상 제한한다.
브라우저는 기본적으로 하나의 서버 연결만 허용되도록 설정되어 있기 때문이다. (주로 자신의 서버)
해결책
클라이언트에서 HTTP 요청의 헤더에 Origin을 담아 전달한다
- 기본적으로 웹은 HTTP 프로토콜을 이용하여 서버에 요청을 보내게 되는데,
- 이 때 브라우저는 요청 헤더에 Origin 이라는 필드에 출처를 함께 담아 보내게 된다.
서버는 응답 헤더에 Access-Control-Allow-Origin 을 담아 클라이언트로 전달한다.
- 이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin 이라는 필드를 추가하고 값으로 이 리소스를 접근하는 것이 허용된 출처 url 을 내려보낸다.
클라이언트에서 Origin 과 서버가 보내준 Access-Control-Allow-Origin 을 비교한다.
- 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin 과 서버가 보내준 응답의 Access-Control-Allow-Origin 을 비교해본 후 차단할지 말지를 결정한다.
- 만약 유효하지 않다면 그 응답을 사용하지 않고 버린다.
- 위의 경우에는 둘다 유효하니 다른 출처의 리소스를 문제없이 가져오게 된다.
서버에서 Access-Control-Allow-Origin 헤더에 허용할 출처를 기재해서 클라이언트에 응답하면 되는 것이다.
관련 링크
https://escapefromcoding.tistory.com/724
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
'브라우저&네트워크' 카테고리의 다른 글
HTTP 와 HTTPS 차이점 (0) | 2023.08.10 |
---|---|
TCP와 UDP (0) | 2023.08.09 |
쿠키와 세션 (0) | 2023.08.08 |
HTTP Method (0) | 2023.08.06 |
HTTP 상태코드 (0) | 2023.07.05 |