SQLインジェクション対策は非常に簡単です。しかしブラウザに対する「スクリプトインジェクション」はなかなか無くなりません。スクリプトインジェクションが無くならない10の理由をあげてみます。
複雑な攻撃経路と対策
前回紹介したように,ブラウザに対するスクリプトインジェクション攻撃の経路は3種類あります。エスケープ方法も数種類あります。すべての出力を完全にエスケープできればセキュリティ維持も容易になりますが,タグや属性を出力したい場合もあるため,必ずしもすべての出力をエスケープできるわけではありません。さらに攻撃手法にも,サイトをまたがった攻撃,直接攻撃,間接攻撃などパターンがあります。エスケープできないデータへの不正なスクリプトの挿入を防ぐには,データの起源までさかのぼり安全性を確保しなければなりません。ブラウザに対するスクリプトインジェクション対策はデータベースサーバへのSQLインジェクション対策に比べ非常に複雑で難しい対策です。
新しい技術やブラウザの導入
新しい技術やブラウザは思いもよらない脆弱性を含んでいる場合があります。XMLHttpReuqest利用の普及により,DOMベースのスクリプトインジェクションに脆弱なWebサイトを構築してしまうリスクが増えました。ブラウザ側での対策が進み,以前に比べれば随分安全にスクリプトを実行可能になりましたが,スクリプトインジェクションの攻撃経路が増えたことには変わりありません。加えてブラックリストによるインジェクション対策は間違ったセキュリティ対策と言えますが,多くのサイトがブラックリスト方式によるセキュリティ対策に頼っていると考えられます。E4X(JavaScriptのXMLサポート)や「data://」URIの追加,通常では予想ができないブラウザの動作など(ダウンロードしたHTMLファイル内のスクリプトがダウンロード先のコンテクストで実行される,XMLHttpRequestがクロスドメインで実行できる(古いKHTMLでは可能だった)など)は,ブラックリスト方式のスクリプトインジェクション対策のみでなく,厳格なホワイトリストによる適切な入力値の検証と出力のエスケープ処理を行っているアプリケーションのセキュリティ対策でさえ無効にしてしまう場合があります。
ブラウザ本体でなく,プラグインの不具合によりスクリプトの挿入・実行が可能になってしまっていた例も少なくありません。ブラウザ本体の不具合と同様に,プラグインの不具合によるセキュリティ上の問題をサーバ側で対処するのは限界があります。
10月26日にリリースされたMac OS Xでは新しいSafariが付属しています。ベータテスト段階で多くのセキュリティ研究者が新たなセキュリティ問題を指摘されました。リリース版に新しいスクリプトインジェクション脆弱性があってもおかしくありません。Mac OS X 10.5は数日で200万本出荷されたとされています。
知識不足
すべてのWeb開発者はブラウザに対する「スクリプトインジェクション」を正しく理解していなければなりません。「フレームワークを利用しているので安全」などと勘違いしていると脆弱性を作ってしまいます。Web開発に従事する方すべてがどのような攻撃方法があり,どのように対策するのか正しい知識を持っていなければなりません。
PHPは簡単な文法を習得するだけでWebアプリケーションが簡単に構築できます。習得が簡単なのは良い事ですが,必要不可欠なセキュリティ対策の知識なしで作られたWebアプリケーションには必ずセキュリティホールやセキュリティ上重大な脆弱性がある,と考えても構わないでしょう。SQLインジェクションのように対策が簡単なセキュリティ上の問題もなくなっていません。知識不足によるブラウザに対するスクリプトインジェクション脆弱性がなくならないのは当然と言えます。
コードの独り歩き
Web開発者がスクリプトが挿入される仕組みや危険性を理解していても,コードがどのように利用される可能性があるのか理解していないと脆弱性を作ってしまう場合があります。プロトタイプやサンプルコードなどにはセキュリティ対策がまったく無い場合があります。この事を知らずに別の開発者がセキュリティ対策を追加せずにそのまま使ってしまうケースはよくあります。
Webサイトや書籍や雑誌に掲載されているコードをコピーして利用する場合,必要なセキュリティ対策が追加されているか十分注意する必要があります。ほかのオープンソースアプリケーションのコードをコピーして利用する場合,コピーしたコードが動作することだけを確認するのでなく,コードが安全に動作するためにどのようなセキュリティ対策が行われているか確認し,不足している場合は必要なセキュリティ対策を追加してから利用しなければなりません。
リソース不足
安全なWebアプリケーション開発には十分なリソースが必要です。セキュリティ対策のリソースを確保していない開発プロジェクトでは安全なWebアプリケーション開発は難しくなります。残念ながら多くのプロジェクトは十分なリソースをセキュリティ対策に割り当てていません。リソース不足の多くは顧客の理解不足(不適切な発注),不適切な受注,不適切な見積もりやプロジェクト管理などが原因で発生します。優れた開発者でも十分な開発リソースが無いと安全なアプリケーションの開発はできません。
不適切な対策
不適切なスクリプトインジェクション対策は,知識不足,リソース不足が原因で発生します。ブラック方式でスクリプトインジェクションを防ぐなどの不適切なスクリプトインジェクション対策が利用されているケースは後を立ちません。スクリプトインジェクション対策はホワイトリスト方式で検証し,エスケープ可能な出力はすべてエスケープしなければなりません。
セキュリティ対策の一つとして,そもそも守るべき情報を無くしてしまうという方法があります。しかし,重要な情報を保存していなくても(例えば,匿名の掲示板情報)スクリプトインジェクション対策は必須です。サイトの規模や価値に関係なく,対策がないサイトであればフィッシング詐欺に利用されるなど,ほかのユーザやサイトの攻撃に利用される可能性があります。
特に設計レベルで不適切な対策を採用してしまうと,後で修正するために非常に多くのリソースが必要になるので注意が必要です。
コードレビューの不在
セキュアなアプリケーション開発サイクルにはコードレビューが欠かせません。しかし,多くのプロジェクトで十分なコードレビューが行われている,とは言い難い状況です。出版物に校正が欠かせないないように,アプリケーションのコードレビューは欠かせません。
オープンソースシステムはソースコードが公開されているので多くの開発者によりコードレビューが可能になり,クローズドソースのシステムより安全性が高い,と言われています。しかし,多くのオープンソースアプリケーションで十分なコードレビューが行われていないことが明らかになっています。オープンソースのアプリケーションは安全性が高い,と盲目的に信じるのではなく,自分で確かめるほうが良いです。
国際化の壁
Webアプリケーションの多くは海外で開発されています。多くのアプリケーションは欧米のシングルバイト圏での利用を前提に開発されています。このため,マルチバイト文字を利用した場合,スクリプトの挿入攻撃が可能になるコードになっている場合も少なくありません。PHP場合,デフォルトでマルチバイト文字を扱うモジュール(mbstring)が有効でないため,脆弱になっている場合が多くあります。マルチバイト文字関連のセキュリティ上の問題はPHPアプリケーションのみでなく,PHP本体やデフォルトで付属するモジュールに発見される場合も少なくありません。
フレームワークの不在
Webアプリケーション開発フレームワークを利用すれば安全なWebアプリケーションが自動的に作れる訳ではありません。しかし,Webアプリケーションフレームワークを利用すると比較的容易に安全なWebアプリケーションを構築できます。
PHPの場合,フレームワークなしに開発されたアプリケーションも多くあります。また,PHPには非常に多くのフレームワークがあるためどのフレームワークを選択するか非常に難しくなっています。信頼性の高いフレームワークが広く利用されるとスクリプトインジェクション脆弱性も少なくなると考えられます。
不適切な設定
US CERTとマイクロソフト社が2000年2月にクロスサイトスクリプティング脆弱性に関して注意を喚起するする文書を発表した際に,ダイナミックコンテンツを送信するWebサーバは利用する文字エンコーディングをHTTPヘッダで指定しなければならないと明記しています。しかし,PHPのソースに含まれるphp.iniの設定例では文字エンコーディング設定(default_charset)は未設定で,HTTPレスポンスヘッダには文字エンコーディングが記載されない設定例になっています。
php.iniのdefault_charsetにデフォルト値(iso-8859-1やUTF-8など)を設定すると,実際に送信したテキストの文字エンコーディングがHTTPヘッダで指定した文字エンコーディングが異なると文字化けが発生します。本来はHTTPヘッダで必ず文字エンコーディングを指定すべきですが,デフォルトのphp.ini設定では文字エンコーディングが指定されていません。HTTPヘッダで文字エンコーディングが指定されていないとMETAタグによって指定されている文字エンコーディングが利用され,METAタグもない場合は自動認識される場合があります。自動認識はもちろん,METAタグで文字エンコーディングを指定してもスクリプトインジェクションに脆弱になる場合があります。文字エンコーディングはHTTPヘッダで指定されなければなりません。