許可範囲が広すぎるFastAPIのCORS設定

許可範囲が広すぎるFastAPIのCORS設定

説明

FastAPIやStarletteで、allow_credentials=Trueとともにすべてのオリジンを許可すると、認証情報を伴うクロスオリジンのレスポンスが信頼できないサイトに公開されたり、ブラウザーやフレームワークの要件と矛盾したりする可能性があります。公式文書では、認証情報を許可する場合、allow_origins、allow_methods、allow_headersに["*"]を使わず、それぞれを明示的に指定するよう求めています。

想定される影響

  • ブラウザーが認証情報の送信を許可する場合、信頼できないサイトからセッションCookieなどを伴うリクエストが送信される可能性があります。
  • 機密性のあるAPIレスポンスが、意図しないフロントエンドや悪意あるサイトに公開される可能性があります。
  • ポリシーとレスポンスヘッダーが一致しないと、正当なブラウザーのリクエストも失敗する可能性があります。CORS設定は、サーバー側の認証や認可を代替しません。

対処方法

  • allow_credentials=Trueを使用する場合は、allow_origins、allow_methods、allow_headersを明示的な許可リストで制限してください。
  • 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"],
)

説明:

  • 変更前: 認証情報を許可しながら、オリジン、メソッド、ヘッダーをすべてワイルドカードで指定します。実際にクロスオリジンのレスポンスを読めるかどうかは、レスポンスヘッダーとブラウザーの認証情報の扱いによって変わります。
  • 変更後: 認証情報が必要な場合も、信頼するオリジンと必要なメソッド、ヘッダーだけを明示的に許可します。

参考資料