こんにちは。現場の最前線でセキュリティと格闘しているエンジニアの皆さん、お疲れ様です。
今日は、Webセキュリティの「永遠の課題」とも言えるXSS(クロスサイトスクリプティング)について、教科書の丸暗記ではなく、「泥棒からどうやって家を守るか」という視点で、現場の泥臭い戦い方をお話しします。
—
1. XSSって、結局何が怖いの?(家の防犯に例えると)
XSSを理解するのに一番分かりやすいのは、「合鍵」と「怪しい手紙」の例えです。
- 反射型XSS: 玄関先で知らない人が「これ、家主さんからの伝言です!」と偽のメモを渡してくるようなもの。あなたがそのメモを読み上げると、家の鍵が開いてしまう。
- 格納型XSS: 掲示板のような共有スペースに、泥棒が「家の中を自由に歩ける魔法の地図」を隠しておくこと。後から来た他の住人がその地図を開いた瞬間に、家が荒らされます。
- DOM型XSS: 家の外観ではなく、家の中の「鏡の反射」を利用するようなもの。URLの端っこに細工をして、被害者がブラウザ上で自ら罠を起動するように仕向けます。
共通しているのは、「信頼していたはずのWebサイトが、実はあなたを攻撃する道具に変えられている」という点です。
—
2. 自動化ツールは「優秀な警備員」、でも…
最近はDAST(動的アプリケーションセキュリティテスト)ツールが優秀です。Burp SuiteやOWASP ZAPを回せば、数千パターンの攻撃コードを網羅的に試してくれます。
しかし、自動ツールは「窓やドアに鍵がかかっているか」はチェックできても、「その鍵の形が、この特殊な扉に本当に合っているか」までは判断できません。
たとえば、JavaScriptの変数の中にデータを埋め込むような、複雑なコンテキスト(文脈)の場合、自動ツールは「脆弱性があるかも?」とアラートを出すだけで精一杯です。ここで我々エンジニアの出番、つまり「手動検証」が必要になります。
—
3. 手動検証のベストプラクティス:Burp Suiteで「文脈」を壊す
ツールが「怪しい」と指摘した箇所を、手動で追い込んでいきましょう。大切なのは、「どこにデータが入ると、プログラムがパニックを起こすか」を考えることです。
ステップ1:コンテキストを特定する
データがどこに表示されるかを確認します。
なら、ここに表示タグなどで脱出できるか試す。なら、'; alert(1); //のように、クォートを閉じて命令を乗っ取れるか試す。
ステップ2:フィルターを回避する
「」という文字をサーバー側で消しているなら、大文字小文字を混ぜたり()、イベントハンドラ(onerrorなど)を使ってみます。
検証用の攻撃コード例:
// サーバーが '
コメント