과도하게 허용된 FastAPI CORS 설정

과도하게 허용된 FastAPI CORS 설정

설명

FastAPI 또는 Starlette에서 allow_credentials=True와 함께 모든 출처를 허용하면 인증 정보를 사용한 교차 출처 응답이 신뢰하지 않는 사이트에 공개되거나 브라우저와 프레임워크의 요구사항에 맞지 않을 수 있습니다. 공식 문서는 자격 증명을 허용할 때 allow_origins, allow_methods, allow_headers를 ["*"] 대신 명시적인 값으로 설정하도록 안내합니다.

잠재적 영향

  • 브라우저가 자격 증명 전송을 허용하는 경우 신뢰하지 않는 사이트에서 세션 쿠키 등의 인증 정보를 포함한 요청을 보낼 수 있습니다.
  • 민감한 API 응답이 의도하지 않은 프런트엔드나 악성 사이트에 노출될 수 있습니다.
  • 허용 목록과 실제 응답 헤더가 맞지 않으면 정상적인 브라우저 요청도 실패할 수 있습니다. CORS 설정은 서버의 인증·권한 검사를 대체하지 않습니다.

해결 방법

  • allow_credentials=True를 사용할 때는 allow_origins, allow_methods, allow_headers를 모두 명시적 allowlist로 제한합니다.
  • allow_origin_regex=".*", allow_origin_regex="^.*$", allow_origin_regex=".+", allow_origin_regex="^.+$" 같은 전체 허용 정규식은 사용하지 않습니다.
  • 운영 환경에서는 환경별 허용 목록을 분리해 필요한 출처만 허용합니다. 서버의 인증·권한 검사와 필요한 CSRF 보호도 유지합니다.

예시

변경 전

python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

변경 후

python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["Authorization", "Content-Type"],
)

설명:

  • 변경 전: 자격 증명을 허용하면서 출처·메서드·헤더를 모두 와일드카드로 설정합니다. 실제 교차 출처 응답 접근 여부는 응답 헤더와 브라우저의 자격 증명 처리에 따라 달라집니다.
  • 변경 후: credential이 필요한 경우에도 신뢰된 출처와 필요한 메서드/헤더만 명시적으로 허용합니다.

참조