なぜあなたのサイトで「誰かが勝手に操作」できるのか?反射型XSSの正体
こんにちは!セキュリティの世界へようこそ。今日は、Web開発の現場で避けては通れない「反射型XSS(クロスサイト・スクリプティング)」という攻撃について、一緒に紐解いていきましょう。
「XSSって名前は聞くけど、結局何が怖いの?」「自分のサイトは大丈夫かな?」と思っているあなた。大丈夫、一つずつ身近な例えで理解していけば、決して恐れることはありません。
1. 反射型XSSは「手紙のすり替え」と同じ
まず、反射型XSSを身近な例で考えてみましょう。
あなたは、玄関に「名前を書くと、その名前で挨拶してくれる看板」を置いているとします。
通常は、誰かが「山田」と書けば、看板には「こんにちは、山田さん!」と表示されますよね。
しかし、もし悪意のある泥棒がやってきて、名前を書く欄に「こんにちは!……あ、ちなみに家の裏口の鍵、今開けといたからね!」というメッセージを書き込んだらどうなるでしょう?
看板は、何も疑わずにそのメッセージをそのまま表示し、それを見た通行人は「えっ、裏口が開いてるの?」と信じてしまいますよね。
これが「反射型XSS」の仕組みです。
- 入力欄:名札を書く場所
- 反射:看板がそのまま表示すること
- 悪意あるコード:泥棒のメッセージ(JavaScript)
Webサイトが、ユーザーから送られてきたURLパラメータを「そのまま」画面に書き出すとき、攻撃者はそこに「ブラウザを操る命令(JavaScript)」を忍び込ませて、あなたのサイト上で勝手な操作をさせるのです。
2. URLパラメータは「信頼してはいけない」
開発をしていると、ついURLパラメータをそのまま画面に表示したくなりますよね。例えば、検索結果画面で「?keyword=猫」とURLにあれば、「検索結果:猫」と表示するようなケースです。
ここで大切な鉄則があります。それは「ユーザーからの入力は、すべて泥棒のメッセージだと思え」ということです。
URLの末尾に ?name= と付けられたとき、あなたのプログラムが何も加工せずに「こんにちは、さん!」とHTMLに埋め込んでしまうと、ブラウザは「これは文字じゃなくて、実行すべき命令だ!」と勘違いして、そのコードを実行してしまいます。
3. 「サニタイズ」で防犯対策をしよう
では、どうすれば防衛できるのでしょうか?一番の基本は「無害化(サニタイズ)」です。
これは、看板に文字を書く前に「<」や「>」といった、ブラウザが命令と勘違いしやすい記号を、ただの「文字」として扱うように変換することです。
実践:安全なエンコーディング
例えば、JavaScriptで画面に名前を表示する場合、そのまま出力するのではなく、以下のように変換を通します。
// 危険な例:そのまま出力すると命令として実行される可能性がある
// element.innerHTML = userInput;
// 安全な例:テキストとして扱う(エスケープ処理)
function escapeHTML(str) {
return str
.replace(/&/g, “&”)
.replace(//g, “>”) // > を > に変換して無害化
.replace(/”/g, “””)
.replace(/’/g, “‘”);
}
// これなら安心!
const userInput = new URLSearchParams(window.location.search).get(“name”);
document.getElementById(“greeting”).textContent = escapeHTML(userInput);
4. 最後の砦:「CSP(コンテンツセキュリティポリシー)」
もし、うっかりエスケープを忘れてしまった時のための「二重の鍵」も紹介しておきます。それがCSP(Content Security Policy)です。
これはWebサーバーからブラウザに送る「通信のルールブック」のようなものです。HTTPレスポンスヘッダーに以下のように設定します。
CSPの設定例
Content-Security-Policy: default-src ‘self’; script-src ‘self’;
この設定をしておくと、ブラウザは「このサイトは自分自身のサーバーから読み込んだスクリプトしか実行しない!」という厳しいガードを固めてくれます。万が一、攻撃者が悪意のあるスクリプトを埋め込んでも、ブラウザが「許可されていない外部からの命令だ!」と判断して実行をブロックしてくれるのです。
まとめ:セキュリティは「疑うこと」から始まる
反射型XSSは、Web開発における最も古典的で、かつ今でも非常に多い攻撃手法です。
対策のコツをまとめますね。
1. ユーザー入力を信用しない:URLパラメータやフォームのデータは、常に攻撃の可能性があると考えてください。
2. 出力時にエスケープする:HTMLに埋め込む直前に、必ず記号を変換しましょう。
3. CSPで守りを固める:もしもの時のために、ブラウザにルールを教え込んでおきましょう。
セキュリティ対策は、一度やって終わりではありません。でも、こうやって一つずつ仕組みを知っていくことで、あなたの作るWebサイトは、ユーザーにとって「本当に安心できる場所」へと変わっていきます。
ぜひ、今日からあなたのコードを少しだけ疑って、安全な書き方に変えてみてくださいね。応援しています!
コメント