교차 출처 리소스 공유 CORS의 개념 정리

JINSUNG LEE·2021년 7월 29일
0
post-thumbnail
post-custom-banner



웹 서버를 작업 및 관리 도중 오류가 발생했다 하면, 십중팔구 CORS 이 녀석이 문제라고 다들 불만을 토로한다.

그렇다면 도대체 교차 출처 리소스 공유 CORS는 무엇일까 🤔❓

CORS (cross - origin resource sharing)
한 도메인에서 로드되어 다른 도메인에 있는 리소스와 상호 작용하는 클라이언트 웹 애플리케이션에 대한 방법

정보 출처 : Amarzon Web Server

쉽게 정리하자면 타 브라우저에서 다른 출처의 리소스를 공유하는 방법이다.






SOP(Same Origin Policy)

CORS를 설명하기 전 SOP에 대해서 먼저 짚고 넘어가야 한다.

SOP(Same Origin Policy)
다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식

출처는 URL에서 Protocol, Host, Port를 통해 동일한 출처인지 다른 출처인지 판별이 가능하다.

같은 출처인 경우 Same Origin, 다른 출처인 경우 Cross Origin

추가적으로 설명하자면, 인터넷 익스플로어 같은 경우 Port가 달라도 같은 출처로 판별하므로

SOP 규칙에서 어긋난다. (고로 쓰지마라... 🚫 e 아이콘에 클릭도 하지마라..🚫 🚫 )

SOP 보안 예시

  1. 인스타그램 이용자가 로그인하여 사용
  2. 해커가 이용자에게 DM으로 수상한 링크를 보냈는데 이용자가 클릭을 해버림.
  3. 링크를 통해 이상한(❓) 사진을 피드에 박제하는 자동 기능이 실행됨

			그동안 열심히 모았던 팔로워들을 순식간에 잃을 절체 절명의 대위기..

인스타를 자주 이용하는 이용자들에겐 최악의 상황이 벌어진 상태이다.

이를 방지하기 위해 SOP가 중요한 역할을 수행하게 된다.

인스타그램 입장에서는 Origin 출처가 다르므로 Cross Origin이 발동된 관계에 따라

SOP의 절대적 룰이 위반되어 해당 요청을 무시하게 된다.

이렇게 보면 SOP가 새삼 중요하다는 것을 느낄수 밖에,,,,

🚫 SOP에 위반 되는 예시 🚫

  • 다른 도메인 (google.com ➡️ WhatIsThat.com)
  • 다른 하위 도메인 (gmail.google.com ➡️ WhatIsThat.google.com)
  • 다른 포트 (google.com ➡️ google.com:81)
  • 다른 프로토콜 (https://google.com ➡️ http://google.com)






CORS 접근제어

그러나 종종 해당 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 필요할 경우

CORS 교차 출처 리소스 공유 정책이 생긴 것이다.

  • 프리플라이트 요청 (Preflight Request)
  • 단순 요청 (Simple Request)
  • 인증 정보 포함 요청 (Credentialed Request)

CORS에는 3가지의 접근 제어가 있으며, 각각 자세히 설명하겠다.

프리플라이트 요청 (Preflight Request)

프리플라이트는 사전 접근 확인에 가까운 요청이다.

사전 접근 요청은 OPTIONS 메서드를 통해 다른 도메인의 리소스에 접근 요청이 가능한 지 파악하여 확인하는 작업이다.

  1. OPTIONS 메서드를 통해 사전 접근
  2. 사전 접근 완료 후 본 실제 요청(Actual Request)를 보낸다.

프리플라이트 요청 조건

Preflight Request (사전 요청)
OPTIONS /doc HTTP/1.1
Origin: http://foo.example // 요청 출처
Access-Control-Request-Method: POST // 실제 요청의 메서드
Access-Control-Request-Headers: X-PINGOTHER, Content-Type // 실제 요청의 추가 헤더

위의 내용은 프리플라이트에 사전 요청 전 보내야할 조건이다.

실제 요청(Actual Request)에 보낼 요청을 미리 다 작성해서 요청해놓은 셈이다.

프리플라이트 응답 조건

Preflight Response (사전 응답)
Access-Control-Allow-Origin: http://foo.example 서버 측의 허가 출처
Access-Control-Allow-Methods: GET, POST, OPTIONS 서버 측의 허가 메서드
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type 서버 측의 허가 헤더
Access-Control-Max-Age: 86400 응답 캐시 시간

위의 내용은 서버 측에 대한 조건들을 응답 조건으로 걸어둔 내용이다.

응답 캐시 시간에 대해 자세히 설명하자면 해당 시간 동안의 중복 요청 필요 없이

실제 요청(Actual Request)을 바로 허가해주는 조건이다.

만일 해당 조건들이 성립 안했을 경우 발생되는 일
1. CORS 오류 발생
2. 조건이 의도치 않게 simple request 조건에 맞춰진 경우 simple request로 작동됨

굳이 두번 요청할 이유는..?

그 이유는 CORS를 모르는 서버가 있기 때문이며, 이는 즉 CORS 관련 설정이 아무것도 없는 상태이다.

SERVER는 CORS 설정이 없는 관계로 ALLOW-ORIGIN이 없는 상태이며

브라우저를 통해 CORS 에러를 발생시킨다.

그러나 이미 서버 측에서는 요청 조건을 다 수행한 관계로 DELETE 같은 요청이라면 CORS 에러가 발생 전

데이터를 벌써 지우고 난 후의 상황이므로 데이터를 되돌리기에는 늦어버렸다...

결국 이를 방지하기 위해 사전 요청 OPTIONS을 하여 CORS 에러가 발생했는지

사전에 판별하기 위해 프리플라이트 사전 요청이 중요하게 쓰이는 이유이다.






단순 요청 (Simple Request)

프리플라이트 요청과 달리 바로 요청을 보내어 Cross-Origin을 판별할 수 있다.

그러나 다음과 같은 조건에만 요청을 보낼 수가 있다.

  1. GET, POST, HEAD
  2. Content-Type에서 application/x-www-form-urlencoded, multipart/form-data, text-plain
  3. Header는 Accept, Accept-Language, Content-Language, Content-Type만 허용 가능

3가지 조건들이 모두 충족되어야만 단순 요청이 가능하다.






인증 정보 포함 요청 (Credentialed Request)



인증 관련 헤더를 포함할 때 사용하는 요청이며, 주로 다른 출처 간 통신에서 강화된 보안을 원할 경우 이용한다.



Client

속성값설명
same-origin같은 출처 간 요청에만 인증 정보를 담는다
include모든 요청에 인증 정보를 담는다
omit모든 요청에 인증 정보를 담지 않는다

credentials 속성의 기본값은 same-origin 이므로, CORS 정책을 지키기 위해선 include로 변경해야 한다.



Server

  • Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Origin : http://foo.example * 사용 불가

credentials: include는 동일 출처 여부와 상관없이 모든 요청에 인증 정보가 포함되도록

설정되었기 때문에 *의 모든 출처를 허용하는 것은 사용 불가이다.




profile
https://californialuv.github.io/Tech_Blog 이사 갔어용 🌎 🚀
post-custom-banner

0개의 댓글