CORS에 대해

hyeon·2024년 11월 14일

CORS(Cross-Origin Resource Sharing) 이해

CORS(Cross-Origin Resource Sharing)는 웹 애플리케이션이 다양한 원본에 호스팅된 리소스와 상호 작용하는 방식을 관리하기 위해 웹 브라우저에 구현된 보안 기능입니다. CORS는 특히 리소스가 서로 다른 서버에 상주하는 오늘날의 상호 연결된 웹 생태계에서 웹 상호 작용의 보안을 보장하는 데 필수적입니다.

1. CORS란?

CORS는 브라우저가 초기 페이지를 제공한 원본이 아닌 다른 원본에서 리소스를 요청하는 방법을 지정하는 보안 프로토콜입니다. 웹 용어에서 "원본"은 프로토콜, 호스트 이름 및 포트 번호의 조합으로 구성됩니다. 동일 출처 정책에 따르면 웹페이지는 잠재적인 악의적인 접근을 방지하기 위해 다른 출처에서 호스팅되는 리소스에 자유롭게 접근할 수 없습니다. CORS는 원본 전체에서 리소스에 대한 제어된 액세스를 활성화하여 이 정책을 완화하는 방법으로 작동합니다.


2. CORS가 중요한 이유는 무엇인가요?

동일 원본 정책은 웹 상호 작용을 위한 기본 보안 조치로, 승인되지 않은 웹 사이트가 다른 웹 사이트의 데이터에 액세스하는 것을 방지합니다. 그러나 최신 웹 애플리케이션은 종종 다른 도메인에서 호스팅되는 API에 의존합니다. CORS가 없으면 많은 애플리케이션이 다른 출처에서 호스팅되는 리소스와 상호 작용할 수 없기 때문에 효율적으로 작동하는 데 어려움을 겪게 됩니다.

예를 들어, 이러한 URL을 클라이언트의 URL http://store.aws.com/dir/page.html과 비교하여 동일한 출처 또는 교차 출처로 간주되는 URL을 확인하세요

http://store.aws.com/dir2/new.html: 동일한 출처(다른 경로)
http://store.aws.com/dir/inner/other.html: 동일한 출처(다른 경로)
https://store.aws.com/page.html: 다른 출처(다른 프로토콜)
http://store.aws.com:81/dir/page.html: 출처가 다름(포트가 다름)
http://news.aws.com/dir/page.html: 다른 출처(다른 호스트)

브라우저는 특별히 허용되지 않는 한 다른 원본에 액세스하려는 요청을 차단하여 동일 원본 정책을 시행합니다. CORS는 HTTP 헤더를 사용하여 리소스와 상호 작용할 수 있는 출처를 브라우저에 알려줌으로써 보안 액세스를 지원합니다.


3. CORS는 어떻게 작동하나요?

(1) CORS 예시

http://myapp.com에서 실행되는 애플리케이션이 있다고 가정해 보세요. 이 애플리케이션은 http://api.external.com과 같이 출처가 다른 다른 사이트에서 데이터를 가져오려고 합니다. http://api.external.com은 출처가 다르기 때문에 브라우저는 이를 '교차 출처' 요청으로 간주합니다. 보안상의 이유로 브라우저는 http://api.external.com이 명시적으로 허용하지 않는 한 앱이 이 데이터에 액세스하도록 허용하지 않습니다.

(2) The Origin Header

http://myapp.com이 교차 출처 요청을 시도하면 브라우저는 요청과 함께 Origin 헤더를 보냅니다. 이 헤더는 어느 웹사이트가 요청을 하는지 서버(http://api.external.com)에 알려줍니다. 다음과 같이 보일 것입니다:

Origin: http://myapp.com

(3) 서버의 CORS 응답

http://api.external.com이 http://myapp.com의 요청을 허용하도록 설정된 경우 다음과 같이 CORS 헤더 Access-Control-Allow-Origin으로 응답합니다.

Access-Control-Allow-Origin: http://myapp.com

이 헤더는 브라우저에게 “괜찮습니다. 내 리소스에 액세스하려면 http://myapp.com을 신뢰합니다.” 이 헤더로 인해 브라우저는 http://myapp.com의 앱이 데이터를 사용하도록 허용하는 것이 안전하다는 것을 알고 있습니다.

(4) 브라우저 동작

'Access-Control-Allow-Origin' 헤더가 포함된 응답을 받은 후 브라우저는 요청을 계속하여 'http://myapp.com'이 'http://api.external.com'의 데이터에 액세스하도록 할 수 있습니다. 이 헤더가 없으면 브라우저는 요청을 차단하고 'http://myapp.com'의 앱은 데이터에 액세스할 수 없습니다.


4. CORS 실행 전 요청이란 무엇인가요?

CORS 사전 요청은 "복잡함"으로 분류될 때 실제 요청 전에 브라우저에서 보낸 OPTIONS 요청입니다. 복잡한 요청은 일반적으로 서버 데이터를 수정하거나 비표준 헤더 또는 메소드를 포함합니다. 여기에는 'GET', 'POST' 또는 'HEAD' 이외의 메소드, 'application/x-www-form-urlencoded', 'text/plain' 또는 'Content-Type' 이외의 요청이 포함됩니다.

(1) 실행 전 요청

https://example.com에 호스팅된 웹 애플리케이션이 https://api.external.com/data에 있는 서버에 DELETE 요청을 보내려고 한다고 가정해 보겠습니다.

브라우저는 먼저 https://api.external.com/data에 OPTIONS 요청을 보냅니다. 이 OPTIONS 요청은 실제로 아무것도 삭제하지 않습니다. 단지 서버에게 "https://example.com"에서 'DELETE' 요청을 보내도 괜찮을까요?"라고 묻는 검사일 뿐입니다.

브라우저의 OPTIONS 요청은 다음과 같습니다.

OPTIONS /data HTTP/1.1 
Origin: https://example.com => 원본
Access-Control-Request-Method: DELETE => 메소드 지정

OPTIONS는 실행 전 요청에 사용되는 HTTP 방법입니다.
원본은 요청이 어디에서 오는지(https://example.com) 서버에 알려줍니다.
Access-Control-Request-Method는 브라우저가 실제 요청에서 사용하려는 메소드('DELETE')를 지정합니다.

(2) 실행 전 요청에 대한 서버의 응답

CORS을 허용하려면 서버는 권한을 부여하는 헤더로 응답해야 합니다. 다음은 서버가 다시 보낼 수 있는 내용의 예입니다.

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

각 헤더의 역할은 다음과 같습니다.

  • Access-Control-Allow-Headers: 클라이언트가 실제 요청에 포함할 수 있는 모든 헤더를 나열합니다.
  • Access-Control-Allow-Origin: 이 리소스에 액세스할 수 있는 원본을 지정합니다(여기서는 https://example.com).
  • Access-Control-Allow-Methods: 허용되는 HTTP 메서드(GET, DELETE, HEAD, OPTIONS)를 나열합니다.
    이 응답으로 서버는 "예, https://example.com이 나에게 DELETE 요청을 보내는 것을 허용하며, 귀하가 수행할 수 있는 작업은 다음과 같습니다."라고 말합니다.

(4) Access-Control-Max-Age 헤더

때로는 서버에 Access-Control-Max-Age 헤더도 포함됩니다. 이 헤더는 이 권한을 캐시할 수 있는 시간(초)을 브라우저에 알려줍니다.

Access-Control-Max-Age: 86400

이 경우 86400초(24시간)는 브라우저가 다음 24시간 동안 서버의 권한을 기억한다는 의미입니다. 해당 시간 동안 브라우저는 각 교차 출처 요청에 대해 새로운 실행 전 요청을 보낼 필요가 없으며 캐시된 권한만 사용합니다.


5. CORS와 JSONP의 차이점은 무엇인가요?

JSONP

JSONP(JSON with Padding)는 <script> 태그를 사용하여 원본 간 요청을 만드는 데 사용되는 기술입니다. 지정된 콜백 함수를 호출하는 JavaScript 코드로 서버가 응답하도록 하여 'GET' 요청만 허용합니다.
제한사항: JSONP는 보안 수준이 낮으며 'GET' 요청만 지원합니다.

CORS

CORS(Cross-Origin Resource Sharing)는 서버가 허용되는 교차 출처 요청을 제어할 수 있도록 하는 표준화된 방법입니다. HTTP 헤더를 사용하여 허용된 원본, 메서드 및 헤더를 나타냅니다.
장점: CORS는 더 안전하고 여러 HTTP 메서드(GET, POST, DELETE 등)를 지원하며 사용자 정의 헤더를 처리할 수 있습니다.

주요 차이점
JSONP는 동일 출처 정책을 우회하지만 'GET' 요청으로 제한되고 보안 위험이 있는 반면, CORS는 정책 내에서 작동하여 더 나은 보안 제어로 더 넓은 범위의 요청을 지원합니다.


6. CORS 모범 사례

애플리케이션을 안전하게 유지하면서 CORS를 최대한 활용하려면 다음 사례를 고려하세요.

(1) 적절한 액세스 목록 정의

API에 대한 액세스 목록을 설정할 때 API에 액세스할 수 있는 도메인(웹사이트)을 결정합니다. 도메인을 허용하기 위해 '와일드카드'(*)를 사용하는 대신 액세스 권한이 있어야 하는 각 도메인을 구체적으로 나열하는 것이 가장 좋습니다.

예를 들어 https://api.permitted-website.comhttps://news.permitted-website.com만 API에 액세스하려는 경우 액세스 목록은 다음과 같아야 합니다.

https://api.permitted-website.com, https://news.permitted-website.com

와일드카드 사용 피하기
와일드카드(*)를 사용하면 모든 웹사이트에 API 액세스 권한을 부여하는 것입니다. 이는 의도하지 않은 사이트와 잠재적인 남용에 API를 개방하므로 위험할 수 있습니다.

(2) 정규 표현식에 주의하세요

때때로 사람들은 여러 도메인을 한 번에 일치시키기 위해 패턴을 사용하려고 합니다.

(예시: api.permitted-website.com 및 news.permitted-website.com을 허용하기 위해 *.permitted-website.com을 사용)

하지만 조심하지 않으면 역효과를 낳을 수 있습니다. 예를 들어 'permitted-website.com'으로 끝나는 도메인을 허용하면 'maliciouspermitted-website.com'과 같은 악성 사이트에도 액세스할 수 있습니다.

가장 안전한 접근 방식은 신뢰할 수 있는 각 도메인을 별도로 나열하는 것입니다.

(3) "null" 출처 방지

다음과 같은 경우에 브라우저는 요청 헤더에서 원본을 null로 설정할 수 있습니다.

요청은 HTTP가 아닌 로컬 파일에서 이루어집니다.
=> localhost로부터의 요청입니다.

'null' 출처를 허용하면 실수로 무단 요청에 대한 액세스 권한을 부여할 수 있으므로 보안 위험이 될 수 있습니다. 액세스 목록에 'null'을 추가하지 않는 것이 가장 안전합니다. 알려진 특정 도메인만 허용하세요.


7. AWS는 CORS 요구 사항을 어떻게 지원할 수 있나요?

AWS는 특히 Amazon S3 및 API Gateway와 같은 서비스에서 CORS를 처리하는 여러 가지 방법을 제공합니다.

  • Amazon S3: S3를 사용하면 각 버킷에 대한 CORS 설정을 구성할 수 있습니다. 버킷의 CORS 구성에서 허용되는 원본, 메서드, 헤더를 직접 지정할 수 있습니다.
  • Amazon API Gateway: API 기반 애플리케이션의 경우 AWS API Gateway를 사용하면 간단한 토글을 통해 API에서 CORS를 활성화하고 CORS 헤더를 자동으로 처리하여 규정 준수를 보장할 수 있습니다.

참고자료: https://aws.amazon.com/ko/what-is/cross-origin-resource-sharing/

profile
당근🥕

0개의 댓글