剣 KENSAI
← 블로그로 돌아가기
웹 보안 2026년 4월 3일 18분 읽기

CORS 구성 오류 취약점: 탐지 및 예방 완전 가이드

CORS 구성 오류는 버그 바운티 프로그램에서 가장 일관되게 보상받는 취약점 중 하나이며, 동시에 가장 과소평가된 취약점 중 하나입니다. 잘못 구성된 Access-Control-Allow-Origin 헤더 하나가 인증된 모든 API 엔드포인트를 공격자가 통제하는 도메인에 노출시킬 수 있습니다.

~35%
CORS 문제가 있는 웹 앱
$3K+
평균 버그 바운티 지급액
치명적
자격 증명 노출 시
OWASP A05
보안 구성 오류

CORS란 무엇이며 왜 중요한가?

ℹ️ 동일 출처 정책(SOP)

기본적으로 브라우저는 동일 출처 정책(Same-Origin Policy, SOP)을 적용합니다. attacker.com에서 실행되는 JavaScript는 bank.com의 응답을 읽을 수 없습니다. CORS는 이 제한을 완화하는 메커니즘으로, 잘못 구성되면 SOP를 완전히 무력화할 수 있습니다.

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 서버가 자신의 출처 이외에 어떤 출처(도메인 + 스킴 + 포트)가 응답을 읽을 수 있는지 나타낼 수 있게 해주는 HTTP 헤더 기반 메커니즘입니다.

이해해야 할 핵심 헤더:

⚠️ 위험한 조합

가장 치명적인 취약점은 서버가 Access-Control-Allow-Origin: [공격자 통제 도메인]Access-Control-Allow-Credentials: true를 함께 반환할 때 발생합니다. 이는 공격자가 자신의 사이트에서 인증된 요청을 보내고 응답을 읽을 수 있음을 의미합니다.


CORS 구성 오류 패턴

1. Origin 헤더 무조건 반영

# 취약한 서버측 로직 (Python/Flask)
@app.after_request
def add_cors(response):
    origin = request.headers.get('Origin')
    response.headers['Access-Control-Allow-Origin'] = origin  # 절대 이렇게 하지 마세요
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    return response

어떤 출처든 인증된 응답을 읽을 수 있게 됩니다. 이것은 버그 바운티에서 발견되는 가장 흔한 CORS 취약점입니다.

2. 취약한 Origin 검증 (부분 문자열/정규식 우회)

# 취약: 신뢰할 수 있는 도메인이 Origin 어디에든 포함되어 있는지 확인
if 'trusted-bank.com' in request.headers.get('Origin', ''):
    # 우회: evil-trusted-bank.com 또는 trusted-bank.com.evil.com 등록
    allow_origin(origin)

3. Null Origin 신뢰

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

null 출처는 샌드박스 iframe, 리디렉션, file:// URL을 통해 트리거될 수 있습니다.


탐지: CORS 구성 오류 찾기

curl을 이용한 수동 탐지

# 테스트 1: 기본 반영 확인
curl -s -I -H "Origin: https://evil.com" \
  https://target.com/api/userinfo \
  | grep -i "access-control"

# 테스트 2: Null origin
curl -s -I -H "Origin: null" \
  https://target.com/api/userinfo \
  | grep -i "access-control"

# 테스트 3: 서브도메인 우회
curl -s -I -H "Origin: https://target.com.evil.com" \
  https://target.com/api/userinfo \
  | grep -i "access-control"

응답에서 확인할 사항

응답심각도악용 가능?
ACAO: *낮음-보통자격 증명 없이만 가능
ACAO: [악성 출처]보통자격 증명 없이
ACAO: [악성 출처] + ACAC: true치명적예 — 전체 자격 증명 도용
ACAO: null + ACAC: true높음샌드박스 iframe 통해

예방: CORS 구성 강화

허용 목록 기반 Origin 검증 (올바른 방법)

# Python/Flask - 안전한 구현
ALLOWED_ORIGINS = {
    'https://app.company.com',
    'https://admin.company.com',
    'https://company.com'
}

@app.after_request
def add_cors_headers(response):
    origin = request.headers.get('Origin')
    if origin in ALLOWED_ORIGINS:
        response.headers['Access-Control-Allow-Origin'] = origin
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        response.headers['Vary'] = 'Origin'  # 캐싱을 위해 필수!
    return response

CORS 보안 체크리스트

CORS 구성 오류 자동 탐지

KENSAI는 모든 API 엔드포인트에서 CORS 구성 오류, 반영된 origin 취약점, null-origin 신뢰 문제를 지속적으로 스캔합니다.

무료 스캔 시작 →

보안은 선택이 아닙니다.

🗡️ KENSAI 팀