正規表現パターンでオリジンをマッチする

正規表現パターンを使用してCORSオリジンを動的に検証します。ワイルドカードサブドメイン、Vercelプレビュー URL、動的ステージング環境の処理方法を解説します。

Common Issues

詳細な説明

正規表現ベースのオリジン検証

多くのサブドメインや動的に生成されるオリジン(Vercelプレビューデプロイメントなど)がある場合、静的な許可リストの維持は現実的ではありません。正規表現マッチングを使用すると、パターンに対してオリジンを検証できます。

よく使われるパターン

パターン マッチ対象
^https://.*\.example\.com$ example.comの任意のサブドメイン
^https://.*\.vercel\.app$ Vercelプレビューデプロイメント
`^https://(app admin
^https?://localhost(:\d+)?$ 任意のポートのlocalhost

Express.js実装

const corsOptions = {
  origin: (origin, callback) => {
    if (!origin) return callback(null, true);

    const patterns = [
      /^https:\/\/.*\.example\.com$/,
      /^https:\/\/.*\.vercel\.app$/,
    ];

    const isAllowed = patterns.some((pattern) => pattern.test(origin));
    if (isAllowed) {
      callback(null, true);
    } else {
      callback(new Error("Not allowed by CORS"));
    }
  },
  credentials: true,
};

Nginx実装

if ($http_origin ~* "^https://.*\.example\.com$") {
    set $cors_origin $http_origin;
}

if ($http_origin ~* "^https://.*\.vercel\.app$") {
    set $cors_origin $http_origin;
}

add_header Access-Control-Allow-Origin $cors_origin always;
add_header Vary Origin always;

セキュリティ警告

正規表現パターンには十分注意してください。不適切な正規表現は悪意のあるオリジンを誤ってマッチする可能性があります:

パターン 脆弱性
example.com evil-example.comにマッチ
^https://example\.com $がない — example.com.evil.comにマッチ
.*\.example\.com ^とプロトコルがない — http://にマッチする可能性

常に両端をアンカー^$)し、パターンにプロトコルを含めてください。

VercelプレビューURL

Vercelはhttps://my-app-abc123.vercel.appのようなURLを生成します。これをサポートするには:

const isAllowed = /^https:\/\/my-app-[a-z0-9]+\.vercel\.app$/.test(origin);

すべての.vercel.appドメインにマッチするよりも安全で、他者のVercelデプロイメントを許可しません。

ユースケース

Vercelをデプロイに使用するチームが、本番環境(app.example.com)とプレビューURL(my-app-abc123.vercel.app)の両方でCORSを動作させる必要があります。常に変化するプレビューURLに対して静的な許可リストでは対応できません。

試してみる — CORS Header Builder

フルツールを開く