【ITニュース解説】Hardening a Vercel app: CSP, CORS, and Service Workers that don’t bite
2025年09月19日に「Dev.to」が公開したITニュース「Hardening a Vercel app: CSP, CORS, and Service Workers that don’t bite」について初心者にもわかりやすく解説しています。
ITニュース概要
Vercelアプリの堅牢化について。CSPで安全なリソースを許可し、CORSでAPIアクセス元を限定。Service WorkerはUIをキャッシュしAPIは除外することで、セキュリティとパフォーマンスを両立させる具体的な設定方法。
ITニュース解説
Webアプリケーションの硬化、つまりハーデニングとは、サイバー攻撃からシステムを守り、安定動作を確保するセキュリティ対策強化のことだ。VercelとFirebaseで構築された『Pocket Portfolio』というアプリケーションを例に、CSP(Content Security Policy)、CORS(Cross-Origin Resource Sharing)、Service Workerという主要技術が、安全性と速度を両立させるためにどのように設定されているかを解説する。
Content Security Policy(CSP)は、Webサイトのセキュリティを強化する仕組みの一つだ。Webページが読み込むリソースの種類や場所をサーバー側で指定し、クロスサイトスクリプティング(XSS)攻撃などの悪意あるスクリプト実行やデータ盗難を防ぐ。vercel.jsonで設定されるCSPは、default-src 'self'で自サイトからのリソース読み込みを許可する。その上で、Firebase AuthenticationなどのGoogleサービスやCDNなど、アプリケーションが利用する外部サービスについてはURLを具体的に指定して許可する。これにより、スクリプト、画像、API通信、iframeコンテンツの読み込み元を細かく制限する。frame-ancestors 'none'は自サイトが他のサイトにiframeとして埋め込まれるのを完全に防ぐ。unsafe-inlineはインラインスクリプトなどを一時的に許可するが、セキュリティリスクに注意が必要だ。upgrade-insecure-requestsはHTTPリソースをHTTPSに自動アップグレードし、安全な接続を確保する。CSPを適切に設定することで、予期せぬスクリプト実行を防ぎ、外部連携機能もスムーズに動作する。
次に、CORS(Cross-Origin Resource Sharing)について解説する。Webブラウザの『同一オリジンポリシー』は、あるWebサイトのスクリプトが異なるオリジン(ドメイン、プロトコル、ポートのいずれかが異なるもの)のデータに直接アクセスするのを制限する。CORSは、このような異なるオリジン間のリソース共有を安全に許可する仕組みだ。APIサーバー側で、Access-Control-Allow-Originヘッダーを使って、どのオリジンからのアクセスを許可するかを明示的に指定する。VercelのサーバーレスAPIでCORSを実装する際は、https://pocketportfolio.appという特定のオリジンだけを許可することで、アプリケーションのフロントエンドからのみAPIへのアクセスを許可する。Access-Control-Allow-Methodsは許可するHTTPメソッドを、Access-Control-Allow-Headersはリクエストで送信できるヘッダーを指定する。プリフライトリクエスト(OPTIONSメソッド)にも適切に応答し、安全な通信経路を確立する。CORSを適切に設定することで、APIを必要以上に公開することなく、自サイトからの安全なデータ連携を実現する。
三つ目の主要技術はService Workerだ。これはWebブラウザのバックグラウンドで動作するスクリプトで、オフライン対応、高速化、プロक्सी機能を提供する。記事では、『アプリを壊さないService Worker』をテーマに、安全かつ効果的な設定方法が示されている。最も重要な原則は、『UIに必要な静的ファイルはキャッシュして高速化するが、APIへのリクエストはService Workerで横取りしない』という点だ。APIからのデータは常に最新であるべきで、古いキャッシュデータはアプリケーションの動作を破綻させる可能性があるため、この分離が極めて重要だ。Service Workerはinstallイベントでアプリの基本的な構成要素をキャッシュし、activateイベントで古いキャッシュをクリアする。fetchイベントがネットワークリクエストを処理し、自サイト以外のリソースや/app/パス以外のリソースは対象外とする。特に/api/パスへのリクエストはService Workerで処理せず、直接ネットワークに流すことで、APIキャッシュを完全に防ぐ。静的アセットには『キャッシュファースト』戦略を、ページ遷移には『ネットワークファースト、キャッシュフォールバック』戦略を用いる。Service Workerは開発環境であるlocalhostでは開発を妨げることがあるため、本番環境でのみ登録するように設定されている点も重要だ。
これらの主要な対策に加え、さらなるセキュリティとパフォーマンス向上のためのいくつかの対策も紹介されている。X-Content-Type-Options: nosniffヘッダーは、ブラウザがMIMEタイプを勝手に推測するのを防ぎ、スニッフィング攻撃を防止する。Referrer-Policy: strict-origin-when-cross-originは、異なるオリジンへのリクエスト時にリファラー情報を制限し、プライバシー保護を強化する。Permissions-Policyは、Webページがブラウザの特定の機能へのアクセスを完全に拒否する。アセットキャッシュ最適化として、Cache-Control: public, max-age=31536000, immutableで静的アセットを長期間キャッシュし、ロード時間を短縮する。さらに、レート制限によってAPIへの短時間での大量リクエストを防ぎ、サーバーへの負荷増や攻撃からAPIを守る。
これらのCSP、CORS、Service Workerといった主要な対策と、追加の硬化策を組み合わせることで、アプリケーションはセキュリティを確保しつつ、高いパフォーマンスとユーザー体験を提供できる。モダンなWebアプリケーション開発において、これらの技術を適切に理解し実装することは、開発者にとって不可欠なスキルとなるだろう。