CORS ? 쉽게 알아보자

홍인열·2022년 3월 18일
0
post-thumbnail

CORS?

Cross-Origin Resource Sharing 문자그대로 해석하면 교차 출처 리소스 공유..음
알아보기에 앞서! 왜 CORS라는게 생겼는지 부터 알아보자

그게 앞서 SOP(Single Origin Policy)에 대해 먼저 알아보자.

SOP

동일 출처 정책(same-origin policy)은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 동일 출처 정책은 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여줍니다. - MDN -

동일 출처 란?

프로토콜 / 호스트 / 포트 3가지가 모두 동일하면 동일 출처라고 할 수 있다.

기준URL동일 출처 인가?
기준http://pick.trip.com/dir/other
http://pick.trip.com/dir3/other1동일 출처 - 경로만 다름
https://pick.trip.com/dir/other동일 출처 X - 프로토콜이 다름
http://pick.trip.com:81/dir/other동일 출처 X - 포트다름(기본 http:// 는 80, https:// 는 443)
http://show.trip.com/dir/other동일 출처 X - 호스트 다름

동일 출처가 아닌데 ajax 요청을 보내면 CORS error를 만나게 된다.
📌 즉! 동일출처가 아닐때 요청을 막는것은 SOP 이고, 요청이 가능하도록하는게 CORS 이다.

왜 동일 출처정책이 왜필요할까 ?

문제 상황을 예로들어보자
1. 유저가 어떤사이트에 접속하고 로그인을하면, 브라우저의 토큰등의 로그인 정보가 쿠키에 저장된다.
2. 이때 로그인 했던 사이트에 접속할때 쿠키를 요청에 같에 보내어 로그인되었다고 판단한다.
3. 즉, 인증정보가 브라우저의 쿠키, 세션등의 스토리지에 저장되어있고 이를 특정 요청에 같이 실어보내어 인증을 진행하는 것이다.
4. 만일 악의적인 사이트가 있다면 해당 사이트 접속시 자바스크립트 코드가 유저의 브라우저에 다운로드되게 된다.
5. 악의적인 사이트의 자바스크립트코드가 유저의 브라우저에 저장된 쿠키나 세션등에 접근할 수 있다.
6. 이를 이용해 유저의 인증정보를 이용해 정보를 탈취할 수 있게된다.

다시 CORS를 쉽게 풀어보자면

동일 출처가 아니더라도 서로 요청과 응답을통해 리소스를 주고 받을 수 있도록 해주는 정책이다.
특정 조건을 충족한다면 리소스 공유를 가능하도록 하는 메커니즘이 CORS!

어떻게 가능하게 할까?

Simple Request

  1. GET, HEAD, POST 의 메서드를 사용
  2. 수동 설정 가능 header는 Accept, Accept-Language, Content-Language, Content-Type .
  3. Content-Type의 값으로 설정가능한 것은 application/x-www-form-urlencoded, multipart/form-data ,text/plain
    의 조건이 갖춰지면 Simple Request라고 하며 다음의 방법을 통해 응답을 받을수 있다.

요청을 받는 백앤드에서 허용할 사이트를 명시해 주면된다!
spring이나 django, Express등의 문서에 CORS 옵션설정하는 방법이 잘나와있다.

요청시 header의 origin항목에 URL(프로토콜/호스트/포트) 정보가 담겨있고, 응답 header에 Access-Control-Allow-Origin항목에 요청시 origin 항목의 URL 정보가 있다면 브라우저는 응답을 받아오게되고 없다면, 거부하게되며 CORS error가 나타나게 된다.
Access-Control-Allow-Origin:* 처럼 와일드카드(*)를 사용하면 모든 origin 요청을 허용하는게 된다.

토큰과 같은 사용자 식별정보가 담긴 요청시

더 엄격한 비교를 통해 응답을 받을 수 있다.
요청하는 쪽에서는 옵션을 withCredentials:true 셋팅하고,
응답하는 쪽에서는 Access-Control-Allow-Origin 항목에 와일드카드(*) 가 아닌 정확한 출처를 명시해야하며,
Access-Control-Allow-Credentials:true로 맞춰줘야 응답을 받을 수 있다.

Preflighted request

PUT, DELETE, FATCH 같이 Simple Request가 아닌 경우에는 본요청을 보내기전 Preflighted request 를 먼저 보내고, 안전한지 확인 한 후에야만 요청을 보낼 수 있다. 이런 요청은 요청만으로도 서버의 데이터에 영향을 줄수도 있기때문에 요청전에 미리 안전한지 확인을 하게된다.

profile
함께 하고싶은 개발자

0개의 댓글