브라우저가 교차 도메인 요청을 차단하는 이유는 무엇인가요?
프론트엔드 개발 중 'Access-Control-Allow-Origin' 오류를 마주한 적이 있나요? 이는 시스템 오류가 아니라 사용자를 보호하기 위한 '동일 출처 정책(Same-Origin Policy, SOP)'이라는 메커니즘 때문입니다. SOP는 서로 다른 출처(프로토콜, 도메인, 포트가 다른 경우)에서 온 웹 코드가 다른 출처의 민감한 데이터에 직접 액세스하지 못하도록 제한합니다.
동일 출처 정책과 CORS의 핵심 차이
동일 출처 정책은 브라우저의 기본 동작이지만, CORS(Cross-Origin Resource Sharing)는 안전한 전제하에 서버가 특정 외부 출처에 데이터 액세스를 적극적으로 허용할 수 있도록 하는 메커니즘입니다. HTTP 헤더 교환을 통해 서버는 허용된 출처를 명확하게 정의할 수 있습니다.
단순 요청과 프리플라이트 요청의 판단 기준
모든 요청이 복잡한 CORS 핸드셰이크를 거쳐야 하는 것은 아닙니다. HTTP 메서드와 헤더의 복잡도에 따라 브라우저는 요청을 '단순 요청'과 '비단순 요청'으로 분류합니다.
| 요청 유형 | 특징 | 프리플라이트 (Preflight) |
|---|---|---|
| 단순 요청 | GET/POST, 표준 헤더만 사용 | 불필요 |
| 비단순 요청 | 커스텀 헤더나 PUT/DELETE 메서드 사용 | 필요 (OPTIONS) |
프리플라이트 요청(Preflight Request)의 작동 메커니즘
비단순 요청의 경우 브라우저는 먼저 OPTIONS 요청을 서버로 보내 '이 요청을 보내도 되는지'를 묻습니다. 서버가 응답을 통해 허용된 출처와 메서드를 반환하면, 그 후 실제 요청을 보냅니다.
흔히 발생하는 CORS 설정 오류
- Access-Control-Allow-Origin을 와일드카드(*)로 설정하고 인증 정보(Credentials)를 허용함.
- OPTIONS 요청을 제대로 처리하지 않아 프리플라이트가 실패함.
- 필수적인 Access-Control-Allow-Headers가 누락됨.
- 모든 출처를 개방하여 잠재적인 사이트 간 공격 위험에 노출됨.
API의 CORS 헤더를 올바르게 설정하는 방법
서버 측 설정 시 '최소 권한 원칙'을 따라야 합니다. 별표(*)를 사용하는 대신 허용된 Origin을 명확히 지정하십시오. 쿠키를 전달해야 하는 앱의 경우 Access-Control-Allow-Credentials를 true로 설정하고 Origin이 *로 되어 있지 않은지 확인하십시오.
현대적 API 설계의 보안 고려 사항
CORS 외에도 Content-Security-Policy(CSP) 및 X-Content-Type-Options와 같은 다른 보안 헤더를 함께 검토하는 것이 좋습니다. 이러한 메커니즘을 통합하면 XSS 및 사이트 간 요청 위조(CSRF) 위험을 크게 줄여 웹 애플리케이션의 안정성을 확보할 수 있습니다.