前回はWeb開発に不慣れな開発者が行いがちな,不適切なクロスサイトスクリプティング対策を紹介しました。今回は適切な対策を理解するために必要な,クロスサイトスクリプティングの本質とクロスサイトスクリプティングの種類について解説します。
クロスサイトスクリプティングの名称
「クロスサイトスクリプティング」は,よくある攻撃方法を表した名前です。サイトをまたがって攻撃用のJavaScriptコード(スクリプト)を送るので,「クロスサイト」「スクリプティング」と命名したものと考えられます。
単語の頭文字を取ると「CSS」となりますが,カスケーディングスタイルシートの「CSS」と同じになり,区別できないので「XSS」と表記されるようになりました。クロスサイトスクリプティングの解説情報には「XSS」ではなく「CSS」と表記している場合もあります。
しかし残念ながらこの名前は直感的な名前とはいえません。初めてこの名前を聞いて,どのような攻撃があり,どのように対処を行えばよいのか直感的に分かる人はいないと思います。
クロスサイトスクリプティングは悪意のあるJavaScriptコードやVBScriptコードをHTMLやCSSに挿入することにより攻撃を行います。ほかのWebアプリケーション脆弱性の代表である,悪意のあるSQLコードを挿入するSQLインジェクション,悪意のあるコマンドを挿入するコマンドインジェクションと同じ「挿入型」の攻撃です。
主にJavaScriptを挿入する攻撃が多いため,JavaScriptインジェクションとも呼ばれます。OWASP(Open Web Application Security Project)では,SQL, XML, LDAP, JavaScript, VBScript等,広い意味でのインタープリタにコードを挿入する攻撃であるので「インタープリタインジェクション」と呼ぶ呼び方もあります。「インタープリタインジェクション」を「スクリプトインジェクション」と呼ぶ場合もあります。PHP,Perl,Rubyのコード挿入攻撃もスクリプトインジェクション攻撃と呼ばれています。
Internet ExplorerにはVB Scriptのインジェクションも可能なので,脆弱性の呼称としてはJavaScriptインジェクションよりスクリプトインジェクションのほうがより的確な名前と考えています。あまり一般的とは言えませんが,本記事ではクロスサイトスクリプティングではなくスクリプトインジェクションを脆弱性名として利用することにします。
スクリプトインジェクションの原因・対策
スクリプトインジェクションはほかのインジェクション攻撃と同じく,完全なバリデーションとエスケープで防御できます。
スクリプトインジェクションはHTML生成のバグ,スクリプトのバグ(後述するType0の脆弱性)のみでなく,以下の機能にバグがあると発生します。
| ブラウザ本体 | Internet Explorer, Firefox, Opera, Safariなど |
|---|---|
| インタープリタ | JavaScript, VBScriptなど |
| プラグイン | Flash, Shockwave, Silverlight, Quicktime, Acrobat, Windows Media Playerなど |
Webアプリケーション開発者としては,インタプリタ自身(ブラウザ)やプラグインのバグに十分な回避策を講じるのは難しいです。ブラックリスト方式では制御した状態で安全性を保つのは非常に困難です。ホワイトリスト方式であれば予測不能なブラウザのバグであっても自然と回避できる場合が多くあります。例えば,「javascript」という文字列の途中に改行,ヌル文字等の制御文字が挿入されていても,ブラウザが「javascript」という一続きの文字列として解釈してしまうようなバグは,ホワイトリスト方式で完全にバリデーションするとかなり回避できます。
Webアプリケーション開発者は可能な限りブラウザ等のバグを回避し,Webアプリケーション開発者の責任範囲であるサーバサイドスクリプト(HTML生成)とクライアントサイドスクリプト(JavaScript,VBScript)にスクリプトインジェクションが可能な脆弱性を作ってはなりません。
ブラウザに対するスクリプトインジェクションの種類
プラグインやブラウザの機能を除くと,スクリプトインジェクションには大きく分けて3種類の攻撃経路があります。あまり一般的とは言えませんが,それぞれType0,Type1,Type2と呼ばれています。
Type0
DOMベーススクリプトインジェクション,ローカルスクリプトインジェクションとも呼ばれるタイプの脆弱性です。クライアント側で入力値を含む値を出力する場合に発生する脆弱性です。スクリプトインジェクションはサーバ側プログラムに不備がなくても攻撃可能な場合があります。例えば,JavaScriptにはwindow.locationオブジェクトがありますが,このオブジェクトのプロパティにはユーザが任意に設定した値が含まれます。これらのプロパティをそのままブラウザに出力すると,スクリプトインジェクションが可能になります。
Type1
攻撃用のURLやページを経由して不正なJavaScriptコードを挿入するスクリプトインジェクションです。ブラウザからの入力を適切にバリデーションせず,エスケープしないために発生する脆弱性です。攻撃用のURLやページを経由しないと攻撃が行われないので,一時的な攻撃と言えます。
Type2
攻撃用のURLやページを経由しないで不正なJavaScriptコードを挿入するスクリプトインジェクションです。Webサイトがブラウザなどからの入力をデータベースなどに保存し,ブラウザに出力している場合に発生する脆弱性です。Type1と異なり脆弱性があるページを表示したブラウザ全てに攻撃可能で,永続的な攻撃になります。

