忍び寄る「毒入りの手紙」:蓄積型XSSというデータベース汚染の恐怖
こんにちは。セキュリティの世界へようこそ。
今日は、Web開発者なら一度は耳にするであろう「XSS(クロスサイトスクリプティング)」の中でも、特にタチが悪い「蓄積型(Stored)XSS」についてお話しします。
教科書には「スクリプトが実行される脆弱性」と書かれていますが、これだと少しピンときませんよね。今日は、私たちの身近な「家の防犯」に例えて、この攻撃の恐ろしさと、私たちがどう守るべきかを紐解いていきましょう。
—
1. 蓄積型XSSのメカニズム:家の中に「泥棒の置き土産」を残される恐怖
想像してみてください。あなたは自分の家の郵便受け(掲示板やプロフィール欄)に、手紙(データ)を投函できるようにしています。
通常、手紙には「こんにちは!」といった挨拶が書かれていますよね。しかし、悪意ある攻撃者は、手紙の中に「この家の合い鍵を勝手に複製して、泥棒に渡す」という呪文(悪意あるJavaScript)を書き込んで投函します。
何が起きるのか?
1. 汚染(保存): 攻撃者が掲示板に投稿した「呪文」が、あなたのデータベース(家の金庫)にそのまま保存されます。
2. 実行(被害): あなたや他のユーザーがその掲示板を開いた瞬間、ブラウザは「手紙の内容を読んで」と命令されます。その手紙には「ブラウザに保存されたCookie(家の合い鍵)を、攻撃者のサーバーへ送信しろ!」という命令が書かれています。
一度データベースが汚染されると、そのページを見る人全員が被害に遭います。これが「蓄積型」の恐ろしさです。反射型XSS(使い捨ての攻撃)と違い、一度汚染されると、誰かが掃除(修正)するまで被害が止まらない「永続的な地雷」なのです。
—
2. 実践!なぜ「そのまま保存」がダメなのか?
開発の現場でよくある失敗は、「入力された内容を、そのままデータベースに放り込んでしまうこと」です。
悪いコードの例(PHP)
// ユーザーが入力したコメントをそのままデータベースへ保存
$comment = $_POST[‘comment’];
$sql = “INSERT INTO posts (content) VALUES (‘$comment’)”;
// このまま保存すると、 も保存されてしまいます
このコードの何が問題か分かりますか? 玄関の鍵をかけずに、誰でも勝手に部屋に物を置ける状態にしているのと同じです。「入力されたものは、すべて何かしらの悪意が含まれているかもしれない」と疑うのが、セキュリティの第一歩です。
—
3. 鉄壁の守り:どうやって防ぐのか?
対策は大きく分けて2つあります。「掃除」と「拒否」です。
対策①:出力時のエスケープ(HTMLエンティティ化)
データを表示する際、ブラウザに「これは命令ではなく、ただの文字だよ」と教えてあげる必要があります。これを「エスケープ」と呼びます。
// 表示する直前に変換する
//
コメント