Gapus Dev Blog

[CS] CORS에 대해 본문

CS

[CS] CORS에 대해

Gapus 2023. 12. 6. 08:00

CORS(Cross-Origin Resource Sharing)

 

설명

 

  • 웹 애플리케이션에서 다른 도메인의 리소스에 접근하는 것에 허용하는 보안 메커니즘
  • 웹 브라우저는 보안 상의 이유로 동일 출처 정책(Same-Origin Policy)을 따르는데, 이는 스크립트나
    스타일시트, 폰트 등과 같은 리소스를 동일한 출처에서만 로드할 수 있도로 제한
  • 출처는 프로토콜, 호스트, 포트로 구성되며, 이 출처가 다를 경우 동일 출처 정책에 의해 접근이 차단
  • 웹 애플리케이션에서 다른 도메인의 API를 사용하거나, CDN을 이용하여 리소스를 제공하는 등 다양한 상황에서
    사용하여 보안을 유지하면서도 다른 도메인과의 연동을 가능하게 한다.

 


 

우회 방법

 

서버 측에서 CORS 설정 변경

 

  • 서버 측에서 CORS 설정을 변경하여 허용해야 할 출처를 추가하거나, 필요한 경우 모든 출처를 허용하는
    대신 특정 도메인만 허용하도록 설정을 변경 가능

 

프록시 서버 사용

 

  • CORS 오류가 발생하는 경우, 프록시 서버를 사용하여 원격 서버로의 요청을 보내고, 프록시 서버에서는 CORS 설정을 처리하는 방법 존재
  • 클라이언트는 프록시 서버에 요청 보내고, 프록시 서버가 원격 서버로의 요청을 처리하고 응답을
    클라이언트에게 반환

 

JSONP(JSON with Padding) 사용

 

  • CORS를 우회하기 위한 대안으로 사용 가능
  • JSONP는 스크립트 태그를 사용하여 다른 도메인에서 데이터를 로드 가능하게 함
  • JSONP는 보안 취약점을 가질 수 있으므로, 신중하게 사용

 

CORS 브라우저 확장 프로그램 사용

 

  • 브라우저 확장 프로그램을 사용하여 특정 도메인에서의 CORS 정책을 우회하는 방법 존재
  • 확장 프로그램은 개발 및 디버깅 목적으로 사용될 수 있지만, 일반적인 사용에는 권장되지 않는다.

 


필요한 이유

 

보안

 

  • 웹 브라우저의 동일 출처 정책은 보안을 위해 도입하여 악의적인 웹 사이트로부터 사용자 정보가
    유츌되는 것을 방지
  • 동일 출처 정책은 동일한 출처에서만 리소스를 로드할 수 있도록 제한하기 때문에, 다른 도메인의
    리소스에 접근이 필요한 경우에는 CORS를 사용하여 보안과 필요한 상호작용을 조화 가능

 

외부 API 사용

 

  • 웹 애플리케이션은 종종 외부 API를 사용하여 데이터를 가져오거나 서비스를 이용
  • 이때, CORS를 허용함으로써, 웹 애플리케이션은 다른 도메인의 API에 접근하여 필요한 데이터를
    요청하고 응답을 받을 수 있다.

 

CDN 사용

 

  • CDN은 전 세계에 분산된 서버를 통해 정적 리소스를 효과적으로 제공하는 기술
  • 웹 애플리케이션에서 CDN을 사용하기 위해서는 CORS를 허용해야 함
  • 다른 도메인의 CDN에서 제공하는 리소스를 사용할 수 있으며, 사용자에게 빠른 로딩 속도와
    향상된 성능을 제공 가능

 

협업과 통합

 

  • 웹 개발은 종종 다른 도메인에 속한 다른 웹 애플리케이션과의 통함을 필요로 한다.
  • CORS를 허용함으로써, 다른 도메인의 웹 애플리케이션과 데이터를 공유하고 서로간에 상호작용 가능
  • 협업이 용이해지고, 다양한 서비스 및 리소스의 활용 가능

 


사용할 때 주의할 점

 

출처 검증

 

  • CORS를 설정 할 때 도메인(출처)를 정확하게 검증해야 한다.
  • 출처를 정확하게 설정하지 않으면 보안상의 취약점이 발생할 수 있다.
  • 출처를 검증하는 방법에는 와일드카드( * )를 사용하는 것보다 명시적으로 특정 도메인을 지정하는 것을 권장

 

필요한 출처만 허용

 

  • 필요한 출처만을 허용하도록 CORS를 설정해야 한다.
  • 모든 출처를 허용하거나 와일드카드( * )를 사용하는 것은 보안상의 위험 발생 존재
  • 필요한 출처만을 하용하여 최소한의 권한을 부여하는 것이 좋다.

 

CSRF 공격 방어

 

  • CORS를 사용할 때는 CSRF(Cross-Site Request Forgery) 공격에 대한 방어를 고려
  • CSRF 공격은 악의적인 웹사이트가 사용자의 권한으로 다른 도메인의 요청을 보내는 것을 의미
  • 이를 방지하기 위해 요청에 CSRF 토근을 포함시키거나, 도메인 간 요청에 대한 검증 절차를
    추가하는 등의 보안 메커니즘을 적용해야 한다.

 

사전 요청 처리

 

  • 복잡한 요청인 경우, 사전 요청을 처리해야 한다.
  • 사전 요청은 본 요청을 보내기 전에 브라우저가 서버에 사전 요청을 보내어 허용 여부를 확인하는 과정
  • 서버는 사전 요청에 대한 응답을 올바르게 처리해야 한다.

 

보안 설정 확인

 

  • CORS 설정을 구성할 때, 서버 측에서도 보안 설정을 확인해야 한다.
  • CORS를 허용하더라도 서버 측에서 충분한 보안 설정을 갖추지 않으면 악의적인 요청을 받을 수 있다.
  • 서버 측에서도 적절한 인증, 권한 부여, 입력 검증 등의 보안 조치를 적용해야 함

 

 


설정하는 방법

 

1. 서버사이드 설정

 

  • 서버 측에서 CORS를 허용하도록 설정해야 한다.
  • 이를 위해 서버의 설정 파일이나 코드에서 CORS 관련 헤더를 추가하거나 설정해야 한다.

 

2. Access-Control-Allow-Origin 헤더 설정

 

  • 서버에서 응답 헤더에 Access-Control-Allow-Origin 헤더를 포함시켜 허용할 도메인을 지정해야 한다.
  • 이 헤더의 값으로는 허용할 출처의 도메인을 명시하거나, 모든 출처를 허용하기 위해 와일드카드( * )를 사용

 

필요한 경우 추가 헤더 설정

 

  • CORS 요청에서 추가적인 헤더를 사용하려면, 서버 응답에 해당 헤더를 포함시켜야 한다.
  • 예를 들어, Content-Type이나 Authorization과 같은 사용자 지정 헤더를 사용하려면,
    서버 응답에 Access-Control-Allow-Headers 헤더를 포함시켜야 한다.

 

사전 요청 처리

 

  • 복잡한 요청인 경우, 사전 요청을 처리해야 한다.
  • 사전 요청은 OPTIONS 메서드를 사용하여 서버에 사전 요청을 보내고, 서버는 이에 대한 응답을 처리해야 한다.
  • 사전 요청에 대한 응답으로 Access-Control-Allow-Methods 헤더를 포함시켜 허용되는 메서드를 지정해야 한다.

 

보안 설정 검토

 

  • CORS를 허용하는 경우에도 보안 설정을 갖추어야 한다.
  • 인증, 권한 부여, 입력 검증 등의 보안 조치를 적절히 구성해야 한다.

 

설정하는 코드 예시

 

// Express.js를 사용하는 경우
const express = require('express');
const app = express();

// CORS 설정
app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', 'http://example.com'); // 허용할 도메인을 지정
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); // 허용할 HTTP 메서드를 지정
  next();
});

// 서버 실행
app.listen(3000, function() {
  console.log('서버가 3000 포트에서 실행되었습니다.');
});

 

 


오류 처리 코드 예시

 

// XMLHttpRequest를 사용하는 경우
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://api.example.com/data', true);
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // 요청이 성공적으로 완료된 경우
      console.log(xhr.responseText);
    } else {
      // CORS 오류 처리
      console.error('CORS 오류가 발생했습니다.');
    }
  }
};
xhr.send();

// Fetch API를 사용하는 경우
fetch('http://api.example.com/data')
  .then(function(response) {
    if (response.ok) {
      return response.json();
    } else {
      // CORS 오류 처리
      throw new Error('CORS 오류가 발생했습니다.');
    }
  })
  .then(function(data) {
    console.log(data);
  })
  .catch(function(error) {
    console.error(error);
  });

 


 

'CS' 카테고리의 다른 글

[CS] Webpack, Babel, Polyfill에 대해  (0) 2023.12.07
[CS] SPA와 MPA에 대해  (0) 2023.12.05
[CS] npm에 대해  (0) 2023.12.01
[CS] 이벤트 캡처링과 이벤트 버블링에 대해  (0) 2023.11.22
[CS] 이벤트에 대해  (0) 2023.11.21