【テクニカル・上級編】Content-Security-Policy (CSP) の厳格なディレクティブ設計とnonce/hashの活用 – アプリケーションセキュリティ & 安全な開発防御ガイド

XSSという「終わったはずの脆弱性」を葬り去る:CSPによる防御の極致

「XSS対策? エスケープ処理を徹底すればいいだけの話だろう」

もしあなたが設計会議でそう口にするなら、その組織のセキュリティレベルは10年前に取り残されていると言わざるを得ない。今日の攻撃者は、WAFのシグネチャを回避し、フレームワークのテンプレートエンジンを悪用し、さらには「DOMベースの汚染」を巧妙に操る。クライアントサイドのスクリプト実行権限を奪うことは、もはや単なる情報の盗み出しではない。それは、ユーザーのブラウザを「攻撃者のエージェント」へと変貌させることを意味する。

今回は、パッチを当てるだけの対処療法を卒業し、ブラウザの挙動を直接制御する「Content-Security-Policy(CSP)」による、本質的な防御アーキテクチャについて語ろう。

—

なぜ「従来型のCSP」は敗北するのか

多くの開発者が設定する script-src 'self' https://trusted.cdn.com; といった緩いCSPは、実戦ではほぼ無力だ。CDN上にホストされているライブラリのバージョンが古く、その中に脆弱性が含まれていれば、それだけで突破口となる(いわゆる「Script Gadgets」攻撃だ)。

真のセキュリティアーキテクトが目指すべきは、「ホワイトリスト方式の限界」を超えた、非決定論的な攻撃すら無効化する「厳格なCSP」である。

—

厳格なCSP:NonceとStrict-Dynamicの共演

XSSを完全に封じ込めるための現代的な回答が、strict-dynamic と nonce(ナンバー・ワンス)の組み合わせだ。

1. Nonce(暗号論的乱数)の活用

各リクエストごとに生成される推測困難な乱数を、スクリプトタグに付与する。CSPヘッダーとHTML側のタグが一致しない限り、ブラウザはそのスクリプトを一切実行しない。

CSPヘッダーの例
Content-Security-Policy: script-src ‘nonce-ed7a4b9c1f2e3d4a’ ‘strict-dynamic’; object-src ‘none’; base-uri ‘none’;



2. ‘strict-dynamic’ の真価

strict-dynamic を指定すると、nonceが付与されたスクリプトから動的に読み込まれた子スクリプトに対しても、自動的に「信頼」が継承される。これにより、CDNからロードする正当なライブラリが、必要な依存関係を呼び出す際の妨げにならず、かつ攻撃者が注入したスクリプトは実行されないという「安全性と利便性の両立」が可能になる。

—

現場で陥る「見えない罠」とアーキテクチャの監査

「CSPを導入したらサイトが壊れた」という悲鳴は、インフラエンジニアの日常だ。しかし、それは設計の甘さを露呈しているに過ぎない。以下のチェックリストを常に念頭に置いてほしい。

  • unsafe-inline の排除: これを許可した時点で、CSPの防御壁には巨大な穴が開く。古いIE対応のために付けているなら、そのコードベース自体をリファクタリングすべきだ。
  • base-uri 'none' の重要性: 意外と見落とされるのがこれだ。 タグを悪用されると、相対パスで読み込まれるスクリプトの基点を外部サーバーにすり替えられる。
  • レポート収集: report-to または report-uri を活用し、CSP違反を必ずログ収集せよ。攻撃の兆候は、誰よりも早くブラウザが教えてくれる。

—

プロンプトインジェクションとの対峙

今、我々が直面している最大のリスクは、生成AIの回答をクライアントサイドで直接レンダリングするアプリケーションだ。AIが生成したテキストに潜む onerror 属性や

securityintronationalをフォローする

コメント

タイトルとURLをコピーしました