Cross-Origin Resource Policy (CORS)

Kim Yongbin·2022년 10월 12일
0

GDSC

목록 보기
4/6

Same Origin Policy (SOP)

한 origin에서 로드된 문서나 script 다른 origin의 리소스와 상호작용하는 것을 제한하는 보안 정책이다.
보안을 위협하는 문서나 script를 분리하여 공격 받을 수 있는 경로를 제한할 수 있다.

즉, 웹 브라우저의 보안을 위해 같은 origin을 갖는 서버로만 AJAX 요청을 주고 받을 수 있다.

Origin

Scheme(protocol) + hostname(domain) + port

⇒ protocol, domain, port가 모두 일치해야 같은 origin이다.

한계

동일 출처 정책(SOP)를 사용하면 같은 origin끼리만 통신을 할 수 있다. 즉, 클라이언트는 3000포트로 실행하고 서버를 8000포트로 실행을 하게 된다면 SOP에 위반이 되는 것이다.

개발을 하다보면 외부 API를 사용하는 경우도 많고, 클라이언트와 서버를 분리하여 진행하는 경우도 많다. 이럴 때마다 SOP로 인해 에러가 발생하는 불편함을 자주 겪는다. 이를 해결하기 위해 나온 것이 Cross-Origin Resource Policy(CORS)이다.

Cross-Origin Resource Policy (CORS)

추가 HTTP 헤더를 이용하여 서로 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 웹 브라우저에 알려주는 방식이다. 즉, 웹 브라우저는 다른 Origin의 리소스를 요청할 때, cross-origin http request를 실행한다.

이러한 CORS request 방식에는 크게 2가지가 있다.

  1. Simple Request
  2. CORS preflight

Simple Request

CORS preflight를 발생시키지 않는 request이다.

Simple Request 조건

  1. HTTP Method 다음 중 하나
    • GET
    • POST
    • HEAD
  2. Content-Type 다음 중 하나
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  3. XMLHttpRequest에 event가 등록되지 않아야 한다.
  4. No ReadableStream Object in request

→ 이후 서버에서 Access-Control-Allow-Origin = {client-server-origin} 를 통해 브라우저에 허용하는 도메인임을 알려줘야 한다.

CORS preflight

Simple request 조건을 만족시키지 못할 경우 브라우저가 자동으로 생성한다. 브라우저는 OPTION method를 통해 다른 origin인 서버에 HTTP request를 보내 실제 request를 전송하기에 안전한지 확인한다. 안전하다고 판단될 시 실제 요청을 보내게 된다.

Example

  • Preflight request
OPTIONS /resources/post-here/ 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: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

Access-Control-Request-Method: POST

→ 실제 요청에서는 POST로 보낼 것임을 명시

Access-Control-Request-Headers: X-PINGOTHER, Content-Type

→ 실제 요청에서는 해당 헤더와 함께 보낼 것임을 알려준다.

⇒ 이러한 정보들을 바탕으로 서버는 해당 요청을 받을 것인지 말지를 결정한다.


Access-Control-Allow-Origin: https://foo.example

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

⇒ 해당 정보들이 허용되었음을 명시

Access-Control-Max-Age: 86400

→ preflight request를 캐싱할 수 있는 최대 시간 (86400초 = 24시간)

Reference

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

https://dongwooklee96.github.io/post/2021/03/23/sopsame-origin-policy-란-무엇일까.html

https://velog.io/@yejinh/CORS-4tk536f0db

profile
반박 시 여러분의 말이 맞습니다.

0개의 댓글