第 2 章
CORSとCSPの仕組み
モダンWebブラウザには、セキュリティを維持しつつ異なるオリジン間で安全にリソースを共有・制限するための仕組みが備わっています。本章では、特に重要な CORS(オリジン間リソース共有) と CSP(コンテンツセキュリティポリシー) について解説します。
1. CORS(Cross-Origin Resource Sharing)
ブラウザには本来、あるサイト(オリジン)から読み込まれたスクリプトが、異なるオリジンのリソースにアクセスすることを制限する 同一起源ポリシー(Same-Origin Policy) があります。 CORS は、サーバーが特定のオリジンに対してのみ「リソースへのアクセスを許可する」と明示することで、安全にこの制限を緩和する仕組みです。
- オリジン (Origin) とは:
プロトコル+ホスト名(ドメイン)+ポート番号の組み合わせです。https://example.com:443とhttp://example.com:443は異なるオリジン(プロトコルが違う)https://api.example.comとhttps://example.comは異なるオリジン(ホストが違う)
プリフライトリクエスト (Preflight Request)
ブラウザは、データを書き換える可能性のあるリクエスト(POST や DELETE、あるいはカスタムヘッダーを持つ GET)を送信する前に、まず OPTIONS メソッド を使った「事前問い合わせ(プリフライト)」を送信し、通信が許可されているかを確認します。
Rendering diagram...
sequenceDiagram
actor Browser as ブラウザ
participant Server as APIサーバー (api.example.com)
Note over Browser: Webページ (example.com) から<br/>API (api.example.com) へリクエストを試みる
Browser->>Server: 1. OPTIONS (プリフライト) 送信<br/>Origin: https://example.com
Server->>Browser: 2. レスポンス返却<br/>Access-Control-Allow-Origin: https://example.com
Note over Browser: 許可されたことを確認し、本リクエストを送信
Browser->>Server: 3. 実際のAPIリクエスト送信 (GET/POSTなど)
Server->>Browser: 4. データを返却
CORSエラーが発生した場合の対策
CORSエラーは ブラウザがアクセスを遮断した ことで発生します。そのため、クライアント側ではなく、アクセス先の サーバー側 で正しいレスポンスヘッダーを返すように設定する必要があります。
// Node.js (Express) でのCORS設定例
import express from 'express';
import cors from 'cors';
const app = express();
const corsOptions = {
origin: 'https://example.com', // 許可するオリジンを指定 (ワイルドカード '*' はCookieを使用する場合不可)
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization',
credentials: true // Cookieなどの資格情報を許可
};
app.use(cors(corsOptions));
2. CSP(Content Security Policy)
CSP は、ブラウザが読み込みおよび実行を許可するリソース(JavaScript、CSS、画像、フレームなど)のホワイトリストを、Webサーバーがヘッダーを通じて指定するセキュリティ機能です。これにより、XSSなどで悪意あるスクリプトが注入された場合でも、その実行をブラウザ側で防ぐことができます。
CSPヘッダーの設定例
Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedscripts.com; img-src 'self' data:;
default-src 'self': すべてのリソースのデフォルトは、現在のオリジン(自サイト)からのみ許可します。script-src 'self' https://trustedscripts.com: JavaScriptの読み込み元は、自サイトとtrustedscripts.comのみに制限します。インラインスクリプト(HTML内に直接書かれた<script>...</script>)は原則として実行が禁止されます。img-src 'self' data:: 画像は自サイトと Base64 エンコードされたデータスキームからのみ許可します。
Next.js でのメタタグ設定例
HTTPヘッダーを設定できない環境(静的ホスティング等)では、<meta> タグを使って簡易的に設定することも可能です。
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<head>
<meta
httpEquiv="Content-Security-Policy"
content="default-src 'self'; img-src 'self' data:; script-src 'self';"
/>
</head>
<body>{children}</body>
</html>
);
}
まとめ
- CORS は、別オリジンからのアクセスを「許可」する仕組み。サーバーで
Access-Control-Allow-Originを設定する。 - CSP は、自サイトが読み込む外部リソースを「制限」する仕組み。XSSの防御に極めて有効。