「画面に文字を出すだけ」で大惨事?XSSからあなたのサイトを守る「文脈」の極意
こんにちは。セキュリティの世界で長く戦っていると、ときどき「入力された文字をそのまま画面に表示するだけで、なぜこんなに騒ぐの?」という質問をいただきます。
実は、Webの世界で「文字を表示する」というのは、家の中に「何でも書き込める魔法の掲示板」を設置するのと同じくらい、実は危険なことなんです。今日は、サイバー攻撃の代表格「クロスサイトスクリプティング(XSS)」と、その最強の防御策である「文脈に応じたエスケープ」について、泥棒の侵入を例に解き明かしていきましょう。
—
1. XSSって何?:「泥棒への手紙」を掲示板に貼るようなもの
XSS(クロスサイトスクリプティング)を一言で言うと、「悪意のあるプログラムを、あなたのサイトの一部として実行させる攻撃」です。
想像してみてください。あなたのサイトが「伝言板」だとします。本来、利用者は「こんにちは」と書くはずですよね。でも、悪意のある攻撃者は「こんにちは」の代わりに、こんな内容を書き込みます。
> 「この掲示板を見ている人の『秘密の鍵(セッションクッキー)』を、僕のサーバーに送れ!」
もし、あなたのサイトがこの入力を「ただの文字」としてそのまま表示してしまったら、掲示板を見た全員のブラウザが、この「泥棒への手紙」を命令として受け取って実行してしまいます。これがXSSの正体です。
—
2. 防御の基本:「文脈(コンテキスト)」で変える「鍵」の形
さて、ここからが本題です。「全部のエスケープ(文字を安全な形に変換すること)を同じルールでやればいいのでは?」と思うかもしれません。でも、実は「どこに文字を埋め込むか」によって、必要な鍵の形(エスケープの種類)は全く違うんです。
これを「文脈に応じたエスケープ」と呼びます。
① HTMLボディに埋め込む場合
一番シンプルなケースです。
<→<>→>&→&
こうすることで、ブラウザは「これはプログラムの開始タグじゃなくて、ただの文字だな」と理解し、安全に表示してくれます。
② HTML属性に埋め込む場合
のように、タグの属性の中に文字を入れるときは要注意です。攻撃者は "> のように、ダブルクォーテーションを閉じてから新しいプログラムを無理やり割り込ませようとします。
ここでは、" や ' をしっかりエスケープ(" などに変換)することが、泥棒の侵入を防ぐ「強固な鍵」になります。
③ JavaScriptの中に埋め込む場合
これが一番危険です。例えば、ユーザー名に応じてアラートを出すようなコードの場合です。
// 危険!ユーザー入力をそのままJSに埋め込む
const userName = '';
もし入力値が '; alert('XSS'); // だったらどうなるでしょうか?プログラムが強制終了させられ、攻撃者のコードが実行されてしまいます。ここでは、「JS用のエスケープ(Unicodeエスケープなど)」を使い、文字を安全な文字列として隔離する必要があります。
---
3. 実践!安全な開発のためのコード例
現代のフレームワーク(React, Vue, LaravelのBladeなど)の多くは、デフォルトでこのエスケープを行ってくれます。しかし、「あえてエスケープを外す機能(Raw出力など)」を使うときは、泥棒を招き入れている自覚を持ってください。
PHPで安全に表示する例を見てみましょう。
こんにちは、" . $safeOutput . "さん!
";
/
- ポイント:
- ENT_QUOTES を指定することで、ダブルクォーテーションもシングルクォーテーションも
- 両方エスケープします。これが最も堅牢な守り方です。
/
?>
---
4. 最後の砦:「CSP(コンテンツセキュリティポリシー)」
どれだけ気をつけていても、人間ですからミスはあります。そこで、万が一攻撃者が侵入したときに備えて「CSPヘッダー」という「家の防犯警備システム」を設定しましょう。
サーバーからブラウザに向けて、「このサイトでは、外部から読み込んできた怪しいプログラムは絶対に動かすな!」と命令を出すヘッダーです。
Content-Security-Policy: default-src 'self'; script-src 'self';
この設定を入れておけば、万が一攻撃者がスクリプトを埋め込んでも、ブラウザが「許可されていない怪しいコードですね、実行しません!」と拒否してくれます。まさに、二重の鍵ですね。
---
最後に:セキュリティは「泥棒とのいたちごっこ」ではない
セキュリティ対策は、一度やって終わりではありません。しかし、今回お話しした「どこに表示するのか?(文脈)」を常に意識し、「入力値は常に疑う(信用しない)」という姿勢さえあれば、多くの攻撃は防ぐことができます。
最初は難しく感じるかもしれませんが、一歩ずつ、丁寧にコードを書く癖をつけていきましょう。あなたの書いたそのコードが、ユーザーの宝物(個人情報やセッション)を守る「最強の扉」になるのですから。
また次の記事で、より深い防衛術についてお話ししましょう!応援しています。
コメント