【実務・中級編】CSPにおけるnonceとhashを用いたインラインスクリプトの制御 – アプリケーションセキュリティ & 安全な開発防御ガイド

「とりあえずインラインスクリプト許可」は引退の合図だ。CSP nonce/hashによる防御の極意

現場でコードレビューをしていると、今でもたまに見かけるんだ。「CSPの設定が面倒だから、とりあえず unsafe-inline を許可しておこう」という安易な妥協。これ、泥棒に対して「正面玄関の鍵は開けっ放しにしておくから、せめてリビングには入らないでね」と頼んでいるようなものだぞ。

今日は、XSS(クロスサイトスクリプティング)を根本から無力化するための、CSPにおける nonce と hash を活用した「攻めの防御」について語ろう。

なぜ unsafe-inline は悪夢なのか?

攻撃者の視点に立ってみよう。もし君のWebアプリに少しでも入力値のバリデーション漏れや、DOM操作の隙があれば、攻撃者はこう考える。
「よし、 を埋め込んで、全ユーザーのセッションを抜き取ってやろう」

unsafe-inline が有効な環境では、この攻撃は一瞬で成立する。CSPという名の監視カメラがあるのに、泥棒が堂々と顔を出して盗みを働いているのを見逃している状態だ。

nonce と hash:信頼の証明書

この状況を覆すのが nonce(Number used once)と hash だ。

  • nonce: サーバー側でリクエストごとに生成するランダムな文字列。HTML内の




    Nginx での静的設定(補足)

    もしインフラ側でCSPを制御したい場合、Nginxの more_set_headers モジュールを使う手もあるが、nonce はリクエストごとに動的である必要があるため、基本はアプリケーション層(PHP, Python, Node.js等)でヘッダーを制御するのが鉄則だ。

    ただし、ハッシュ値を用いた固定的なスクリプト制限であれば、Nginx側でも対応できる。

    Nginx 設定例
    特定のインラインスクリプトのハッシュ値を許可する例
    add_header Content-Security-Policy "script-src 'sha256-abc123xyz...';";

    現場で絶対に陥ってはいけない「落とし穴」

    多くのエンジニアが躓くポイントが2つある。

    1. strict-dynamic の活用: これを忘れると、読み込んだライブラリがさらに別ファイルを読み込む際にブロックされてしまう。strict-dynamic を付けることで、「信頼できるスクリプトが生成したスクリプト」も信頼するようになる。これはモダンな開発には必須だ。
    2. サードパーティ製タグの扱い: Google Analyticsなどは unsafe-inline を要求することがあるが、これも nonce を付与することで回避できる場合が多い。ドキュメントをよく読め。

    まとめ:防御を「設定」ではなく「文化」に

    いいか、セキュリティとは「ツールを入れること」ではない。「攻撃者が入る隙間を物理的に消すこと」だ。

    unsafe-inline を無効化し、nonce を導入するのは、最初は工数がかかるように思えるかもしれない。だが、一度インフラやフレームワークのテンプレートに組み込んでしまえば、インジェクション攻撃という悪夢の大部分を無効化できる。

    「動けばいい」という甘い考えは捨てて、ブラウザという強力な警備員を味方につけろ。君の書くコードが、誰かの大切なデータを守る最後の砦になるんだ。

    さあ、今すぐ Content-Security-Policy ヘッダーを確認しに行こう。君のアプリケーションの「鍵」は、まだ開いたままになっていないか?

コメント

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