Bin's Blog

CORS란 무엇일까? 본문

Web

CORS란 무엇일까?

hotIce 2023. 9. 3. 09:41
728x90

CORS란? 

브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한한다. 그래서 cross-origin 요청을 하려면 서버의 동의가 필요하다. 만약 서버가 동의한다면 브라우저에서는 요청을 허락하고, 동의하지 않는다면 브라우저에서 거절한다

 

이러한 허락을 구하고 거절하는 메커니즘을 HTTP-header를 이용해서 가능한데, 이를 CORS(Cross-Origin Resource Sharing)라고 부른다. 이를 통해 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처(프로토콜, 도메인, 포트번호)의 리소스에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 

웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차 출처 HTTP 요청을 실행한다. 

 

브라우저에서 cross-origin 요청을 안전하게 할 수 있도록 하는 메커니즘이다. 

 

cross-origin 

cross-origin이란 다음 중 한 가지라도 다른 경우를 의미한다.

 

1. protocol - http와 https는 프로토콜이 다르다.

2. domain - domain.com과 other-domain.com은 다르다.

3. port number - 8080포트와 3000포트는 다르다. 

 

예시

URL 동일 출처? 이유
https://www.domain.com:3000/about O 프로토콜, 도메인, 포트 번호 동일
https://www.domain.com:3000/about?username=hobin O 프로토콜, 도메인, 포트 번호 동일 
http://www.domain.com:3000 X 프로토콜 다름(http != https)
https://www.domain.com:8888 X 포트 번호 다름
https://www.another.co.kr:3000 X 도메인이 다름

 

만약 모두 일치하면 Same Origin이다. 

 

CORS는 왜 필요한가?

CORS가 없이 모든 곳에서 데이터를 요청할 수 있게 되면, 다른 사이트에서 원래 사이트를 흉내낼 수 있게 된다.

출처가 다른 두 개의 애플리케이션이 마음대로 소통하는 환경은 위험한 환경이다. 

웹에서 돌아가는 클라이언트 애플리케이션은 사용자 공격에 매우 취약하다. 

 

해커가 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting) 등의 방법을 이용해서 우리가 만든 애플리케이션에서 해커가 심어놓은 코드가 실행하여 개인 정보를 가로챌 수 있다. 

 

개발자 도구만 열더라도 DOM, JavaScript 코드 등 각종 통신 정보를 쉽게 열람할 수 있다. 이렇게 다른 출처의 애플리케이션이 통신하는 것에 제약이 없다면, 기존 사이트와 동일하게 동작하여 사용자의 정보가 탈취되기 쉬워진다. 

 

Same-Origin Policy(동일 출처 정책)란?

웹에는 크게 SOP(Same-Origin Policy)와 CORS(Cross-Origin Resource Sharing) 두 가지 정책이 있다.

 

SOP(Same-Origin Policy) 정책은 단어 그대로 동일한 출처에 대한 정책을 말한다. 법률적으로 "동일한 출처에서만 리소스를 공유할 수 있다"라고 명시되어 있다. 

 

서버에서 API를 호출할 때는 잘 동작하다가 브라우저에서 API를 호출할 때만 CORS Policy 오류가 발생한 적이 있을 것이다. 

브라우저에서만 오류가 발생하는 이유는 CORS가 브라우저의 구현 스펙에 포함되는 정책이기 때문에 브라우저를 통하지 않고 서버 간 통신을 할 때는 적용되지 않기 때문이다. 

 

 

CORS는 어떻게 동작하나요?

Simple request인 경우

1.서버로 요청한다

2. 서버의 응답이 왔을 대 브라우저가 요청한 Origin과 응답한 헤더 Access-Control-Request-Headers의 값을 비교하여 유효한 요청이라면 리소스를 응답한다. 만약 유효하지 않은 요청이라면 브라우저에서 이를 막고 에러가 발생한다. 

Origin: https://google.com

Simple request란?

HTTP method가 다음 중 하나이면서

  • GET
  • HEAD
  • POST

자동으로 설정되는 헤더는 제외하고, 설정할 수 있는 다음 헤더들만 변경하면서

  • ACCEPT
  • ACCEPT-Language
  • Content-Language
  • Content-type

Content-type이 다음과 같은 경우

  • application/x-www-form-urlencoded
  • multipart/from-data
  • text/plain

Simple request라고 부른다. 이 요청은 추가적으로 확인하지 않고 바로 본 요청을 보낸다

 

preflight 요청일 경우

simple request의 조건을 따르지 않는 경우에는 preflight이 발생한다.

 

1. Origin헤더에 현재 요청하는 origin과, Access-Control-Request-Method헤더에 요청하는 HTTP method와 Access-Control-Request-Headers 요청 시 사용할 헤더를 OPTIONS 메서드로 서버로 요청한다. 이때 내용물은 없이 헤더만 전송한다. 

2. 브라우저가 서버에서 응답한 헤더를 보고 유효한 요청인지 확인한다. 만약 유효하지 않은 요청이라면 요청은 중단되고 에러가 발생한다. 만약 유효한 요청이라면 원래 요청으로 보내려던 요청을 다시 요청하여 리소스를 응답받는다. 

 

prefilght 요청이란?

Simple requests가 아닌 cross-origin 요청은 모두 preflight 요청을 하게 되는데, 실제 요청을 보내는 것이 안전한지 확인하기 위해 먼저 OPTIONS 메서드를 사용하여 cross-origin HTTP 요청을 보낸다. 이렇게 하는 이유는 사용자 데이터에 영향을 미칠 수 있는 요청이므로 사전에 확인 후 본 요청을 보낸다

 

 

Credentialed Request일 경우

인증된 요청을 사용하는 방법으로 CORS 기본적인 방식 보다는 다른 출처 간 통신에서 조금 더 보안을 강화하고 싶을 때 사용하는 방법이다.

 

XMLHttpRequest객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 요청에 담지 않는다.

이때 요청에 인증 관련 정보를 담을 수 있게 해주는 옵션이 바로 credential 옵션이다. 

 

이 옵션에는 3가지의 값을 사용할 수 있다.

옵션 값 설명
same-origin(default) 같은 출처 간 요청에만 인증 정보를 담을 수 있다.
include 모든 요청에 인증 정보를 담을 수 있다
omit 모든 요청에 인증 정보를 담지 않는다.

만약 same-origin이나 include와 같은 옵션을 사용하여 리소스 요청에 인증 정보가 포함되면, 브라우저는 Cross-Origin 리소스를 요청할 때 단순히 Access-Control-Allow-Origin만 확인하는 것이 아니라 조금 더 빡빡한 검사 조건을 추가하게 된다. 

 

 

CORS 해결하기

Access-Control-Allow-Origin 세팅

 

가장 대표적인 방법은 서버에서 Access-Control-Allow-Origin 헤더에 알맞은 값을 세팅하는 것이다. 

Access-Control-Allow-Origin: https://google.com

 

728x90

'Web' 카테고리의 다른 글

시맨틱 태그(Semantic Tag)란?  (0) 2023.11.09
session과 JWT 그리고 OAuth  (0) 2023.09.25
웹 브라우저의 동작원리  (0) 2023.09.22
쿠키와 세션  (0) 2023.07.06