기타 덩덩/늘어나라 테크 지식

[Web] CORS가 뭔데

stop-zero 2023. 5. 1. 02:59
더보기

지금까지 프론트와 백을 배우면서 다르게 구현만 해봤지 같이 합친 경우는 이번이 처음이었다.

아무런 문제 없이 합쳐지기 위해서는 CORS가 그 중심에 있었고 Full stack mini project에 사용했던 CORS에 대해 더 궁금해져서 찾아보게 되었다. 

CORS(Cross-Origin Resourc Sharing)

CORS는 HTTP 헤더 기반 메커니즘으로 처음 리소스를 제공한 도메인이 현재 요청하려는 도메인과 다르더라도 요청을 허락해 주는 웹 보안 방침이다. 

Origin

Origin= 프로토콜+도메인+포트 번호

Origin: https://miunoribird.tistory.com
url : https://miunoribird.tistory.com/62#mount%C2%A0-1

https://   = 프로토콜  miunoribird.tistory.com   =도메인  / 62 =포트번호

url, 도메인과 비슷해보이지만 다른 의미이다.

페이지의 console 창을 열어서 window.location.origin 명령어를 실행하면 현재 접속한 사이트의 origin을 알 수 있다. 



SOP와 CORS의 관계

SOP(Sam Origin Policy) : 동일 출처 정책
CORS: 교차 출처 자원 공유

둘이 그렇고 그런 긴밀한 관계이다.

SOP는 동일한 Origin으로만 요청을 보낼 수 있고,  다른 Origin으로 요청을 보낼 수 없는 브라우저의 보안 정책이다.  

옛날 옛날에는 절대적인 규칙이었지만, 시간이 지나고나서 기술이 발달하니까 다른 Origin끼리도 데이터를 교류해야 했고 이렇게 몇 가지 예외 상황이 생겼다. 

RFC 6454에서 정의한 예외 상황을 짧게 정리하면,

Generally, reading information from another origin is forbidden. However, an origin is permitted to use some kinds of resources retrieved from other origins. For example, an origin is permitted to  execute script, render images, and apply style sheets from any origin. Likewise, an origin can display content from another origin, such as an HTML document in an HTML frame. Network resources can also opt into letting other origins read their information, for example, using Cross-Origin Resource Sharing

다른 Origin으로의 요청도 허용하는 경우

  • <script> 태그로 JS 실행
  • 이미지 렌더링
  • <link> 태그로 스타일 시트 파일 불러오기
  • HTML 문서 화면에 보여주기 
  • CORS 정책을 지키는 경우

우리는 CORS 정책을 지킨다면 다른 Origin으로 요청을 보낼 수 있다.

단, 브라우저의 정책이므로 서버 간 통신에서는 적용되지 않는다. 

서버는 요청이 오면 응답을 하고, 브라우저가 자신이 보낸 요청 및 서버로부터 받은 응답의 데이터가 CORS 정책을 지키는지 검사하여 안전한 요청을 보냈는지 검사한다. 서버는 응답을 했더라도 안전한 요청이 아니면,  해당 응답을 실행시키지 않는다.

 

SOP가 없다면?

악의적인 마음을 품은 해커가 자신의 웹사이트를 구축해놓고, 이 웹사이트를 가리키는 링크를 담은 메일을 사용자에게 보내는 것이다. 그리고 이 사용자는 A라는 웹사이트에 로그인이 되어 있어서 브라우저 단에 인증 정보가 존재한다고 해보자. 만약 그 사용자가 실수로 해당 링크를 클릭하여 해커의 웹사이트에 접속하면, 해커가 심어둔 JavaScript 코드가 실행되어 자기도 모르게 A 웹사이트로 개인 정보를 조회하는 API 요청을 보낼 것이다. 이 사용자의 브라우저 단에는 인증 정보가 존재하기 때문에, 이것이 해당 요청에 함께 실어서 전송되면 서버는 인증된 요청이라 생각하여 개인 정보를 응답해 줄 것이다. 그러고 나면 그 개인 정보를 해커가 빼돌릴 수 있게 된다. (이것이 바로 
CSRF 공격이다.)

SOP가 없으면 내 네이버 중국놈들한테 털린 것처럼 털린다. 내가 네이버 털린 게 정확하게 이 이유인지는 알 수 없지만..

SOP가 존재한다면 해커의 웹사이트 Origin 과 A사이트의 Origin은 다르기에 API 요청을 주고받을 수 없다.  따라서  악의적인 경우를 방지하기 위해, SOP 정책으로 동일하지 않는 다른 출처의 스크립트가 실행되지 않도록 브라우저에서 사전에 방지하는 것이다

 

CORS의 동작원리 

기본적인 동작원리

  1. 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달(=웹은 HTTP 프로토콜을 이용하여 서버에 요청을 보냄 -> 요청헤더에 Origin 이라는 필드에 출처를 함께 담아서 보냄)
  2. 서버는 응답 헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
  3. 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin이라는 필드를 추가하고 값으로 '이 리소스를 접근하는 것이 허용된 출처 url'을 내려보낸다.
  4.  클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다.
  5. 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해본 후 차단할지 말지를 결정한다.
  6. 만약 유효하지 않다면 그 응답을 사용하지 않고 버린다. (CORS 에러 !!)

좀 더 깊게 들어가면 3가지 유형이 존재한다. (간단하게만 알아봤다.. 더 자세히 알아보다가는 내 머리털이 다 사라질 것 같다)

 

단순 요청

단순요청은 MDN에서 사용하는 용어이다. 

단순요청의 조건은 배우 까다롭다. 조건을 만족하면 안전한 요청으로 취급되고 단 한 번의 요청을 전송한다.

위에서 설명한 기본적인 동작원리를 그대로 실행한다. 

 

프리플라이트 요청

단순 요청의 조건을 벗어나는 요청일 때, 예비 요청에 해당하는 프리플라이트 요청을 먼저 보내서 요청이 전송하기에 안전한지 확인한다. 

1) 단순한 요청 벗어남 -> 프리플라이트 요청으로

2) 안전한 요청인가

이렇게 두 가지의 요청을 전송한다.

 

인증 정보를 포함한 요청

말 그래도 인증 정보가 필요한 경우에 별도의 요청이다.

쿠키 등의 인증 정보를 보내기 위해서는 클라이언트에서 요청의 별도 설정이 필요하다. 별도의 설정을 해주지 않으면 인증 정보는 자동으로 서버에게 전송되지 않는다. 

 

더보기