dev-sohee 님의 블로그

웹 보안의 취약점 2탄 : CORS 방어기법 본문

웹 보안의 취약점 2탄 : CORS 방어기법

dev-sohee 2024. 8. 27. 19:54

'웹 보안의 취약점 1탄 : XSS, CSRF 공격기법'에서 공격기법에 대해 알아봤으니 이번엔 방어기법 중 하나인 CORS에 대해 알아보겠습니다. 

 

 

# CORS

CORS는 한국어로 직역하면 '교차 출처 리소스 공유'라고 해석할 수 있습니다. 여기서 '교차 출처(Cross-Origin)'이란 '다른 출처'를 의미합니다. 즉, 도메인이 다른 서버끼리 리소스를 주고 받을 때 보안을 위해 설정된 정책이라고 생각하시면 됩니다. 

예를 들어, 웹 사이트 A가 API 서버에서 데이터를 가져오려 할 때, API 서버에서 CORS 허용 설정이 되어 있지 않으면 웹 브라우저에서 API 접근이 거부될 수 있습니다. CORS 설정은 API 서버에서 HTTP 응답 헤더에 "Access-Control-Allow-Origin" 항목을 추가하여 허용할 도메인을 지정하는 것으로 가능합니다. 이때 같은 출처라고 판단하는 기준은 URL의 구성 요소 중 ProtocolHostPort가 동일하면 같은 출처라고 판단합니다.

출처_https://velog.io/

 

CORS 작동 방식

  • 예비 요청(Preflight Request)
    1) 브라우저는 요청을 한번에 보내지 않고 예비 요청(Preflight Request)과 본 요청으로 나누어서 서버로 전송합니다. 예비 요청은 브라우저가 실제 요청을 보내기 전에 서버가 CORS 정책을 허용하는지 확인하기 위해 보내는 요청으로, HTTP 메소드 중 OPTIONS 메소드를 사용합니다. 이 요청에는 Origin, Access-Control-Request-Method, Access-Control-Request-Headers 등의 헤더가 포함됩니다.
    2) OPTIONS 요청을 받은 서버는 Response Header에 서버가 허용할 옵션을 설정하여 브라우저에게 반환합니다.
    3) 만약 서버가 해당 요청을 허용하면, 브라우저는 실제 요청을 진행합니다. 브라우저는 서버가 보낸 Response 정보를 이용하여 허용되지 않은 요청인 경우 405 Method Not Allowed 에러를 발생시키고, 본 요청은 서버로 전송하지 않습니다. 반대로 허용된 요청인 경우 본 요청을 보냅니다.

    아래 그림은 Preflight Request 동작 플로우입니다.

출처_https://blog.sucuri.net/2024/06/cross-origin-resource-sharing.html

 

  • 단순 요청 (Simple Request)
    : 단순 요청은 말그대로 예비 요청(Prefilght)을 생략하고 바로 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin 헤더를 보내주면 브라우저가 CORS 정책 위반 여부를 검사하는 방식입니다. 다만, 아래 3가지의 조건을 만족하는 경우에만 예비 요청을 생략할 수 있습니다.
    1) 요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
    2) Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width 헤더일 경우 에만 적용된다.
    3) Content-Type 헤더가 application/x-www-form-urlencoded, multipart/form-data, text/plain중 하나여야 한다. 아닐 경우 예비 요청으로 동작된다.
    위 조건을 모두 만족시키기가 어렵기 때문에, 단순 요청이 일어나는 상황은 드물다고 보시면 됩니다.

  • 인증된 요청 (Credentialed Request)
    : 클라이언트가 서버에게 자격 인증 정보(Credential)를 실어 교차 출처 요청을 보내는 경우입니다. 자격 인증 정보란 세션 ID가 저장되어있는 쿠키 혹은 Authorization 헤더에 설정하는 토큰 값 등을 말합니다. 서버는 이 요청이 안전하다고 판단하는 경우에만 인증 정보를 포함한 요청을 처리해야 하고 처리 방법은 다음과 같습니다.
    1) 응답 헤더의 Access-Control-Allow-Credentials 항목을 "true"로 설정해야 한다.
    2) 응답 헤더의 Access-Control-Allow-Origin 의 값에 와일드카드 문자("*")는 사용할 수 없다.
    3) 응답 헤더의 Access-Control-Allow-Methods 의 값에 와일드카드 문자("*")는 사용할 수 없다.
    4) 응답 헤더의 Access-Control-Allow-Headers 의 값에 와일드카드 문자("*")는 사용할 수 없다.

 

장점

 

  • 보안 강화
    : CORS는 기본적으로 브라우저에서 동작하는 동일 출처 정책(Same-Origin Policy)을 보완하여, 악의적인 도메인에서 리소스에 접근하는 것을 방지합니다. 이를 통해 웹 애플리케이션의 보안을 강화할 수 있습니다.
  • 유연한 리소스 공유
    : CORS를 사용하면 서버 관리자가 특정 출처에 대해서만 리소스 접근을 허용할 수 있습니다. 이를 통해 필요한 경우에만 교차 출처 요청을 허용하면서도, 여전히 보안을 유지할 수 있습니다.
  • API 확장성
    : CORS는 공개 API를 제공하는 서비스에서 매우 유용합니다. API 제공자가 특정 클라이언트 도메인만 접근하도록 허용하거나, 모든 도메인에 접근을 허용하여 API의 사용 범위를 확장할 수 있습니다.

**동일 출처 정책(Same-Origin Policy)이란? : 웹 브라우저에서 실행되는 스크립트가 출처(origin)가 다른 리소스에 접근하지 못하도록 제한하는 정책입니다.

 

 

단점

 

  • 설정의 복잡성
    : CORS 설정은 매우 세밀하며, 서버와 클라이언트 간의 상호작용을 잘 이해하지 못하면 오류가 발생하기 쉽습니다. 특히 예비 요청과 같은 복잡한 개념은 초보자가 접근하기 어려울 수 있습니다.
  • 보안 위협
    : 잘못된 CORS 설정은 보안 취약점을 초래할 수 있습니다. 예를 들어, 모든 출처(*)에 대해 리소스 접근을 허용하면 악의적인 사이트에서 중요한 데이터에 접근할 수 있는 위험이 있습니다.
  • 브라우저 의존성
    : CORS는 브라우저에서 적용되는 정책입니다. 브라우저가 아닌 환경(예: 모바일 앱이나 서버 간 통신)에서는 CORS 정책이 적용되지 않기 때문에, 특정 보안 위협을 완벽하게 막을 수 없습니다.

 

 

CORS를 공부하면서 웹 보안과 웹 어플리케이션의 상호작용에 대한 이해가 깊어졌습니다. 이 기술은 웹의 장점인 쉬운 접근성과 보안 사이에서 균형을 맞추기 위한 중요한 도구이며, 이를 제대로 이해하고 활용하는 것이 웹 개발에서 필수적이라고 느꼈습니다. CORS 설정을 올바르게 하지 않으면 웹 어플리케이션의 기능이 제한되거나 보안 취약점이 발생할 수 있기 때문에, 신중하게 다뤄야 할 부분인 것 같습니다.