インラインスクリプトの脅威を「魔法の鍵」で防ぐ!CSPのNonceとHash入門
こんにちは。現場で泥臭いインシデント対応ばかりしているセキュリティエンジニアです。
皆さんは「インジェクション攻撃」という言葉を聞いて、どんなイメージを持ちますか? 難しそうなセキュリティ用語ですよね。でも、実はこれ、私たちの身の回りにある「泥棒」の手口と全く同じなんです。
今日は、Webアプリを「鉄壁の要塞」にするための強力な防衛術、CSP(Content Security Policy)のNonce(ナンス)とHash(ハッシュ)について、専門用語を極力使わずに解説していきます。
—
1. なぜ「インラインスクリプト」が危ないのか?
まず、攻撃者が何を狙っているのかを考えてみましょう。
皆さんのWebサイトに、悪意ある第三者が勝手に「怪しいコード」を書き込んだとします。例えば、「このボタンを押すと、ユーザーのクレジットカード情報を外部に送信する」といったスクリプトです。
これを通称「クロスサイトスクリプティング(XSS)」と呼びます。
なぜこれが防ぎにくいかというと、ブラウザは「自分のサイトに書かれているスクリプトなら、全部信頼して実行しちゃう」という、ちょっとお人好しな性格をしているからです。家の鍵を開けっ放しにして、「この家の人なら誰でも入っていいよ」と言っているようなものですね。
—
2. CSPは「身元確認」の仕組み
そこで登場するのが CSP(Content Security Policy) という技術です。これは、ブラウザに対して「このサイトでは、こういうスクリプトしか動かしちゃダメだよ」と伝える、いわば「通行証」のようなものです。
これを設定しておけば、たとえ攻撃者が怪しいコードを紛れ込ませても、ブラウザが「お前は通行証を持っていないからダメだ!」と追い返してくれます。
では、どうやって「正当なスクリプト」と「泥棒のスクリプト」を見分けるのでしょうか。ここで活躍するのが Nonce(ナンス) と Hash(ハッシュ) です。
—
3. Nonce(ナンス)で「使い捨ての通行証」を作る
Nonce(Number used onceの略) は、その名の通り「一度だけ使える魔法のチケット」です。
1. サーバーがページを表示するたびに、ランダムな文字列(例:EDNnf03nceIOfn39fn3e)を生成します。
2. その文字列を、許可したい タグに nonce 属性として付与します。
3. 同時に、サーバーからブラウザへ「このページでは、nonce="EDNnf03nceIOfn39fn3e" がついているスクリプトだけ実行してね!」とヘッダーで伝えます。
攻撃者の視点: 攻撃者がいくら怪しいコードを埋め込んでも、サーバーが発行した「今この瞬間の正しいNonce値」を知ることはできません。だから、ブラウザは「お前、通行証がないな?」と判定し、実行を拒否してくれます。
実装例:
HTTPヘッダーでの設定例
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e';
---
4. Hash(ハッシュ)で「スクリプトの指紋」を確認する
もう一つの方法が Hash(ハッシュ) です。これは、スクリプトの内容を数学的に変換して「指紋」を作る手法です。
「このスクリプトの内容は、この指紋と一致する場合だけ動かしていいよ」とあらかじめブラウザに伝えておきます。
- メリット: スクリプトの内容が変わらないなら、毎回Nonceを生成する必要がありません。
- デメリット: スクリプトを少しでも書き換えると指紋が変わってしまうため、頻繁に更新するコードには向きません。
実装例:
スクリプトの内容をSHA-256でハッシュ化した値を通行証として指定
Content-Security-Policy: script-src 'sha256-n4eYhG2kOa...';
---
5. 今日からできる一歩
「いきなり全部導入するのは難しそう…」と感じるかもしれません。でも大丈夫。最初は「レポート専用モード」で試すのが、現場のエンジニアの定石です。
以下のヘッダーを試してみてください。
Content-Security-Policy: script-src 'nonce-ランダムな値'; report-uri /csp-violation-report-endpoint/
これなら、いきなりサイトが壊れることはありません。もし怪しいスクリプトが動こうとしたら、あなたのサーバーに「今、誰かが怪しい動きをしましたよ!」と報告が飛んでくるようになります。
最後に:セキュリティは「終わりなき旅」
CSPは強力な武器ですが、これだけで全てが解決するわけではありません。入力値のチェックや、データベースへのクエリの書き方に気を配るなど、日々の積み重ねが一番大切です。
「面倒だな」と思うかもしれませんが、こうして一つずつ対策を理解していくことが、結果としてユーザーの信頼を守り、あなた自身のエンジニアとしての価値を高めてくれます。
まずは、自分のサイトのHTTPレスポンスヘッダーを確認するところから始めてみませんか? 泥棒を寄せ付けない、安全なWebの世界を一緒に作っていきましょう!
コメント