[F-Lab 모각코 챌린지 32일차] CORS Cross-Origin Resource Sharing (1)

Nami·2023년 7월 2일
0

66일 포스팅 챌린지

목록 보기
32/66

CORS Cross-Origin Resource Sharing

교차 출처 리소스 공유, 웹 브라우저에서 실행되는 JavaScript가 다른 도메인(Origin)에 있는 리소스에 접근할 수 있는 권한을 부여하기 위한 메커니즘이다.

  • 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
  • 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.

ex: https://domain-a.com의 프론트 엔드 JavaScript 코드가 XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우

웹 애플리케이션은 보안 상의 이유로 동일 출처 정책(Same-Origin Policy, SOP)에 의해 제한되어 있어, 스크립트가 다른 도메인으로부터 리소스를 요청하는 것은 기본적으로 금지된다. CORS는 웹 애플리케이션에서 보다 유연한 데이터 교환과 API 호출을 가능하게 하기 위해 SOP를 확장하는 개념.

SOP Same-Origin Policy

2011년, RFC 6454에서 처음 등장한 보안 정책. 웹 보안 메커니즘 중 하나로, 웹 브라우저에서 실행되는 JavaScript를 통해 로드된 문서나 스크립트가 동일한 출처(Origin)로부터 로드된 리소스와만 상호작용할 수 있도록 제한하는 정책.

CORS는 SOP을 우회하기 위한 메커니즘 중 하나.

출처 Origin

서버의 위치를 의미하는 https://google.com과 같은 URL들은 마치 하나의 문자열 같아 보여도, 사실은 여러 개의 구성 요소로 이루어져 있음.

출처는 프로토콜(ex: HTTP, HTTPS), 호스트(도메인) 이름, 포트 번호의 조합을 의미. 출처 내의 포트 번호는 생략이 가능한데, 이는 각 웹에서 사용하는 HTTP, HTTPS 프로토콜의 기본 포트 번호가 정해져있기 때문.

http://store.company.com/dir/page.html의 출처를 비교한 예시

URL결과이유
http://store.company.com/dir2/other.html성공경로만 다름
http://store.company.com/dir/inner/another.html성공경로만 다름
https://store.company.com/secure.html실패프로토콜 다름
http://store.company.com:81/dir/etc.html실패포트 다름 (http://는 80이 기본값)
http://news.company.com/dir/other.html실패호스트 다름

WHEN?

교차 출처 공유 표준 참고.

  • XMLHttpRequestFetch API 호출
  • 웹폰트(CSS 내 @font-face에서 교차 도메인 폰트 사용 시)
  • WebGL 텍스쳐
  • drawImage() 를 사용해 캔버스에 그린 이미지/비디오 프레임
  • 이미지로부터 추출하는 CSS Shapes

작동방식

Origin: https://velog.io/@chocoallergie
  • 허용된 출처를 서버에서 설명할 수 있는 새로운 HTTP 헤더를 추가함으로써 동작.
  • 부수 효과를 일으킬 수 있는 HTTP 요청 메서드(GET을 제외한 HTTP 메서드)에 대해서는 CORS 명세에서 브라우저가 사전 전달(preflight)라고 하는 OPTIONS 메서드를 사용하여 서버가 요청을 처리할 수 있는지 확인하고 허용된 출처인지 확인.
    • 부수 효과 Side effect?
      웹 요청을 통해 서버에게 전달되는 동작 중에서 리소스를 수정하거나 변경하는 효과.
      HTTP 메서드(GET을 제외한 메서드)는 서버의 데이터를 변경하는 작업을 수행.
    • CORS에서 부수 효과를 언급하는 이유는 보안 상의 이유로 브라우저에서 다른 출처로 요청을 보낼 때, 해당 출처의 서버가 웹 애플리케이션의 데이터를 수정할 수 있는 가능성이 있기 때문

예시
https://foo.example 의 웹 컨텐츠가 https://bar.other 도메인의 컨텐츠를 호출하길 원한다. foo.example에 배포된 자바스크립트에는 아래와 같은 코드가 사용된다.

const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';

xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();

클라이언트와 서버간에 간단한 통신을 하고, CORS 헤더를 사용하여 권한을 처리함.
브라우저가 서버로 전송하는 내용을 살펴보고, 서버의 응답을 확인함.

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example

요청 헤더의 Origin을 보면, https://foo.example로부터 요청이 왔다는 것을 알 수 있음.

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[XML Data…]
  • 서버는 이에 대한 응답으로 Access-Control-Allow-Origin헤더를 다시 전송
  • 서버는 Access-Control-Allow-Origin: *, 으로 응답
    - 모든 도메인에서 접근할 수 있음을 의미.
  • 응답을 받은 브라우저는 요청의 출처와 서버가 보내준 응답의 출처를 비교하고 유효한지 아닌지를 결정.

다음엔 사전 전달에 대해 블로깅!


참조 ✅

0개의 댓글