-
CORS에 대해 쉽고 빠르게 파헤치기웹 보안 2024. 8. 19. 16:04
목차
- 들어가기 앞서...
- CORS란?
- CORS의 동작 원리 & 동작 방식
- CORS 설정시 주의 사항
1. 들어가기 앞서...
웹 애플리케이션에 대해 공부하다 보면 결국 모든 작업이 클라이언트와 서버, DB간의 요청에서 시작해서 응답으로 끝나는 것을 알 수 있습니다. 필자는 Spring을 공부하지만, 다른 프로그래밍 언어로 웹 애플리케이션을 개발하더라도 저랑 비슷한 감상을 느끼실 것이라고 조심스럽게 예측해봅니다. 이전까지 저는 안전한 웹 애플리케이션은 버그가 최대한 적게 일어나는 것이라고 생각했는데, 시큐어 코딩이라는 개념에 대해 접한 순간부터는 타인의 악의로부터 클라이언트와 서버를 안전하게 보호하는 것까지가 건강한 개발자가 가져야할 마음가짐이라고 생각하게 됐습니다.
2. CORS란?
한 개발자가 웹 애플리케이션을 개발한 후 방화벽에 GET, POST, PATCH, PUT, DELETE 메서드를 허용했습니다. 이후 SPA(Single Page Application)로 개발된 프론트 페이지에 접속하여 요청했을때, 403 Forbbiden, 405 Method Not Allowed라는 에러를 마주했다면, 그 이유는 무엇일까요?
더보기SPA(Single Page Application)
단일 페이지 어플리케이션이라고 일컬어지며, 필요한 데이터만 비동기로 받아와서 동적으로 화면에 렌더링하는 프론트엔드 기술입니다. 컨텐츠를 클릭한다고 화면 전체가 다른 페이지로 넘어가는게 아닌, 같은 페이지에서 필요한 정보만 업데이트되어 클라이언트에게 노출됩니다. 이를 통해 클라이언트는 SPA의 부드러운 페이지 전환과 업데이트 될때까지의 시간이 단축되어 높은 몰입감을 가질 수 있습니다.
아시는 분도 아시겠지만, 그 원인은 SOP(Same-Origin Policy) 때문입니다.
더보기SOP(Same-Origin Policy)
동일 출처 정책으로 일컬어지며, 이름 그대로 웹 브라우저가 스크립트가 로드된 출처와 동일한 출처의 리소스만 접근할 수 있도록 제안하는 보안 매커니즘입니다. 웹 애플리케이션은 기본적으로 SOP에 따라 동작하며, 이는 보안상의 이유로 다른 출처의 리소스 접근을 제한합니다. 여기서 출처란 프로토콜, 도메인, 포트로 구성되어 있으며 출처가 같다는 뜻은 이 세 개의 구성요소가 전부 일치해야함을 말합니다. SOP를 통해 기대할 수 있는건 사용자의 정보 보호, 악의적인 사용자 접근 제한 등이 있습니다.
하지만, 웹 생태계가 급격하게 발전하게 되면서 다른 리소스의 접근을 완화시킬 필요성이 생겼습니다. 예를 들면,
1. 클라이언트 중심의 웹 애플리케이션은 API 호출시 다른 도메인에서 호스팅되는 API를 호출해야할 필요성이 있습니다.
2. 여러 도메인 간의 이미지, 스크립트, 폰트 등의 리소스를 공유할 필요가 있습니다.
여기서 등장한 것이 이번 글의 핵심. CORS(Cross-Origin ResourceS)입니다.
CORS란, 한 출처(프로토콜, 도메인, 포트)에서 실행중인 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 브라우저에서 제공하는 보안 기능입니다. 물론, 모든 상황에서 다른 출처의 리소스에 접근한다면 SOP에 어긋남으로, 특정 조건 하에 다른 출처의 리소스 접근을 허용합니다.
특정 조건하 라는게 CORS의 핵심 동작 원리와 동작 방식에 연동됩니다.
3. CORS의 동작 원리 & 동작 방식
CORS의 동작 원리의 핵심인 preflight에 대해 알아보겠습니다.
preflight 요청은 CORS 요청의 일종으로, 브라우저가 실제 요청을 보내기 전에 서버에 요청할 권한이 있는지 확인하는 과정입니다. 다시말해서 실제 요청이 나가기 전, preflight 요청을 보내 다른 출처의 서버에 허락을 구하는 것입니다. preflight 요청은 보안상의 이유로, 특정조건을 만족하는 http 요청이 서버에 전송되기전에 실행됩니다. 특정 조건은 아래와 같습니다.
- Http 메서드가 PUT이나 DELETE
- 커스텀헤더나 특정 표준헤더를 사용할 때
- application/x-www-form-urlencoded, multipart/form-data, text/plain이 아닌 Content-Type을 사용할때
CORS의 동작 방식은 아래의 순서대로 진행됩니다.
- 브라우저가 서버에 preflight 요청을 보냅니다.
- 서버가 preflight 요청에 응답합니다.
- 브라우저가 서버의 응답을 확인합니다.
4. CORS 설정시 주의사항
CORS는 어떻게 보면 실제 요청을 하기전에 서버에 요청을 한 번 더 보내는 것이기 때문에, 자원이 소모가 됩니다. 따라서, 모든 요청에 대해 CORS 설정을 하게되면 서버에게 들어오는 요청이 두 배가 되어 과부하가 일어납니다. 개발자는 이를 숙지하고 올바른 요청에 CORS를 설정할 수 있도록 해야합니다. preflight가 필요한 요청과 필요하지 않은 요청을 쉽게 preflight request와 simple request로 구분 짓는데, 두 가지의 특징을 알아보도록 합시다.
Simple Request
- 간단한 HTTP요청이란 뜻에 맞게, preflight 요청 없이 바로 서버에 전달되는 요청입니다.
- GET, POST, HEAD 메서드중 하나입니다.
- 응답 헤더에는 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers등이 포함됩니다.
Preflight Request
- Simple Request 조건을 충족하지 않는 요청은 서버의 CORS 정책을 확인하기 윟해 브라우저가 먼저 Options 메서드를 사용하여 Preflight 요청을 보냅니다.
- 서버는 preflight 요청에 적절히 응답하여 요청을 처리합니다.
CORS는 서버에 별도로 설정을 해줄 수 있는데, 아래의 주의사항을 숙지해야합니다.
주의사항
- 신뢰할 수 없는 출처를 허용하지 않는다.
- allowedOrigins옵션에 와일드카드(*) 사용시 모든 출처에서의 요청을 허용해야한다.
- 민감한 정보를 보호하기위해 Access-Control-Allow-Credentials를 신중하게 설정해야한다.
- 성능을 위해 Access-Control-Max-Age를 설정해서 Preflight요청을 캐싱한다.
- 불필요한 Preflight 요청을 최소화하도록 Simple Request로 설계한다.
이번 글에서는 제가 CORS에 대해 공부한 내용을 정리하기위해 적은 내용입니다. 이 글을 볼때 틀린점도 있으니 비판적인 시각으로 봐주시면 감사하겠습니다.
오늘은 CORS에 대해 알아보았고, 다음 글에서는 CSRF에 대해 알아보겠습니다.
'웹 보안' 카테고리의 다른 글
CSRF에 대해서 파헤치기 (0) 2024.08.24