본문 바로가기
일반IT/IT보안

웹 개발자라면 꼭 알아야 할 Same-Origin Policy와 CORS 🌐

by gasbugs 2025. 9. 9.

안녕하세요! 👋 오늘은 웹 개발을 하다 보면 한 번쯤은 마주치게 되는 중요한 보안 정책인 동일 출처 정책(Same-Origin Policy, SOP)과 이를 유연하게 대처하기 위한 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)에 대해 알아보겠습니다. 이 두 가지 개념은 웹 애플리케이션의 보안과 기능성에 직접적인 영향을 미치기 때문에 확실히 이해하고 넘어가는 것이 중요합니다. 자, 그럼 시작해볼까요? 🚀


🛡️ Same-Origin Policy (SOP)란 무엇일까요?

동일 출처 정책(Same-Origin Policy)은 웹 브라우저에 내장된 아주 중요한 보안 기능입니다. 간단히 말해, '같은 출처'에서 온 리소스만 상호작용할 수 있도록 제한하는 정책이죠. 이 정책은 웹 브라우저 자체에 내장되어 있어, 브라우저가 실행하는 스크립트의 동작을 제어합니다. 여기서 '출처(Origin)'는 URL의 세 가지 요소, 즉 프로토콜(Protocol), 호스트(Host), 포트(Port)가 모두 동일한 경우를 의미합니다.

 

예를 들어, https://example.com:80/index.html 이라는 주소가 있다면,

  • 프로토콜: https://
  • 호스트: example.com
  • 포트: :80 (https의 기본 포트는 443, http는 80으로 종종 생략됩니다)

이 세 가지가 모두 같아야 '동일 출처'로 인정됩니다.

URL 비교 대상 (https://example.com) 동일 출처 여부 이유
https://example.com/page.html https://example.com 프로토콜, 호스트, 포트 모두 동일
http://example.com https://example.com 프로토콜 불일치 (http vs https)
https://www.example.com https://example.com 호스트 불일치 (www.example.com vs example.com)
https://example.com:8080 https://example.com 포트 불일치 (:8080 vs :443)
 
이 정책 덕분에 해커가 만든 악성 웹사이트(https://evil-site.com)가 사용자의 중요한 정보가 있는 웹사이트(https://my-bank.com)의 데이터를 마음대로 가져오거나 조작하는 것을 방지할 수 있습니다. 🔒
 

하지만 이 강력한 보안 정책은 때로는 불편함을 초래합니다. 현대 웹 애플리케이션은 다양한 출처의 리소스(API, 폰트, 이미지 등)를 가져와 사용하는 경우가 많기 때문이죠. 예를 들어, 프론트엔드 서버와 백엔드 API 서버의 도메인이 다른 경우, SOP에 의해 데이터 요청이 차단될 수 있습니다. 바로 이 문제를 해결하기 위해 등장한 것이 CORS입니다.


🤝 CORS (Cross-Origin Resource Sharing)란 무엇일까요?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 이름 그대로 다른 출처의 리소스 공유를 허용해주는 정책입니다. CORS는 서버와 브라우저 간의 통신을 통해 이루어지며, 특히 리소스를 제공하는 웹 서버가 응답 헤더를 통해 특정 출처의 요청을 허용할지 결정합니다. SOP라는 엄격한 규칙에 '예외'를 두어, 신뢰할 수 있는 다른 출처의 리소스는 안전하게 가져올 수 있도록 길을 열어주는 것이죠.

 

CORS는 단순히 SOP를 비활성화하는 것이 아니라, HTTP 헤더를 사용하여 서버와 브라우저가 서로 통신하며 특정 출처의 요청을 허용할지 결정하는 방식으로 동작합니다. 즉, 리소스를 제공하는 서버 측에서 '이 출처에서 오는 요청은 허용해도 괜찮아'라고 명시해주면, 브라우저는 해당 응답을 받아 정상적으로 처리합니다.

 

CORS의 동작 방식

CORS 요청은 크게 두 가지로 나뉩니다: 단순 요청(Simple Request)과 프리플라이트 요청(Preflight Request)입니다.

1. 단순 요청 (Simple Request) 💨

특정 조건을 만족하는 간단한 요청은 브라우저가 바로 서버에 본 요청을 보냅니다.

  • 메서드: GET, HEAD, POST 중 하나
  • 헤더: Accept, Accept-Language, Content-Language, Content-Type 등 기본 헤더만 포함
  • Content-Type 헤더: application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나

이 경우, 브라우저는 요청 헤더에 Origin 필드를 추가하여 자신의 출처를 서버에 알립니다. 서버는 응답 헤더에 Access-Control-Allow-Origin 필드를 포함하여 리소스 접근을 허용하는 출처를 명시합니다. 브라우저는 이 값을 보고 요청한 Origin과 일치하면 리소스를 안전하게 받아옵니다. 만약 일치하지 않거나 헤더가 없으면 CORS 에러가 발생합니다. 💥

 

2. 프리플라이트 요청 (Preflight Request) ✈️

단순 요청의 조건을 벗어나는 경우 (예: PUT, DELETE 메서드 사용, Content-Type이 application/json인 경우 등), 브라우저는 실제 요청을 보내기 전에 '프리플라이트(Preflight)'라는 예비 요청을 먼저 보냅니다.

이 예비 요청은 OPTIONS 메서드를 사용하여 서버에 "내가 앞으로 이러이러한 메서드와 헤더로 요청을 보낼 건데, 괜찮을까?"라고 물어보는 과정입니다.

  • 요청 헤더:
    • Origin: 요청을 보내는 출처
    • Access-Control-Request-Method: 실제 요청에서 사용할 메서드
    • Access-Control-Request-Headers: 실제 요청에서 사용할 헤더

서버는 이 프리플라이트 요청을 받고, 허용하는 메서드와 헤더 등을 응답 헤더에 담아 보내줍니다.

  • 응답 헤더:
    • Access-Control-Allow-Origin: 접근을 허용하는 출처
    • Access-Control-Allow-Methods: 접근을 허용하는 메서드
    • Access-Control-Allow-Headers: 접근을 허용하는 헤더
    • Access-Control-Max-Age: 프리플라이트 응답을 캐시할 시간 (초 단위)

브라우저는 서버의 응답을 확인하고, 실제 요청이 허용 범위 내에 있다고 판단되면 그때서야 본 요청을 서버에 전송합니다. 이 과정을 통해 실제 데이터에 영향을 줄 수 있는 요청을 보내기 전에 안전성을 미리 검증할 수 있습니다.


✨ 정리하며

  • Same-Origin Policy (SOP)는 웹의 기본적인 보안 모델로, 다른 출처의 리소스와 상호작용하는 것을 기본적으로 차단합니다.
  • CORS (Cross-Origin Resource Sharing)는 SOP의 제약을 완화하여, 서버의 허락 하에 다른 출처의 리소스를 안전하게 사용할 수 있도록 하는 메커니즘입니다.
  • CORS는 HTTP 헤더를 통해 동작하며, 서버는 Access-Control-Allow-Origin과 같은 헤더로 허용할 출처를 명시해야 합니다.
  • 요청의 종류에 따라 단순 요청 또는 프리플라이트 요청을 통해 교차 출처 리소스 공유가 이루어집니다.

웹 개발 시 마주치는 CORS 에러는 이제 더 이상 두려움의 대상이 아닙니다! SOP와 CORS의 동작 원리를 이해하면, 왜 에러가 발생하는지 파악하고 서버 측에서 적절한 헤더 설정을 통해 문제를 해결할 수 있게 될 것입니다. 😊

궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

 

태그: Same-Origin Policy, CORS, 웹 보안, 프론트엔드, 백엔드, HTTP, 교차 출처 리소스 공유