Webアプリ脆弱性分類とか
2009年1月9日(金曜日)
Webアプリ脆弱性分類とか
公開: 2009年1月9日15時20分頃
「Webアプリの脆弱性は5+1の分類で把握せよ-NTTデータCCS長谷川氏 (enterprise.watch.impress.co.jp)」。
分類って難しいですよね。思ったことをメモ。
暴露問題とは、顧客リストなどの秘密情報が、Webサーバーの基本的振る舞いによって漏えいしてしまうもの。Webアプリケーションの脆弱性が広く認知される前は、公開フォルダに格納された顧客リストが、Webブラウザからファイル名を予測してアクセスするだけで、外部から閲覧できてしまった事例がある。また、URIに「../../../etc/passwd」といった不正なパラメータを挿入し、想定外のパスへアクセスする「ディレクトリトラバーサル攻撃」もこの範ちゅうだ。
フォースフル・ブラウジングによる漏洩とディレクトリ・トラバーサルは性質がかなり違うと思うのですが。
前者はおおむね運用の不備で、ファイルの格納場所を工夫する、不要なファイルを置かないようにする、といった運用が重要になります。それに対して、後者は純粋にWebアプリケーションの脆弱性で、ファイルを何処に置いたって駄目なのですよね。脆弱なアプリケーションの修正が必要です。
分類を同じにしてしまうのは乱暴な気がしますし、ディレクトリ・トラバーサルは「入力問題」ではないかと思いますけれど、どうなのですかね。
XSSの予防的実装例としては、「HTMLコンテンツに入力値をそのまま出力しない」「出力される特殊記号を加工あるいは抑制する」ことが有効。加えて「比較的安全なタグ属性」「タグのURL属性」「タグのstyle属性、イベントハンドラ属性、scriptタグの内側」の3種類の文脈に応じた対策を心がけるようにとしている。
うーん、これはどうなのでしょう。3種類の文脈って……注釈宣言やマーク区間の話が抜けているのはまあ良いとしても、一番多いと思われる、普通に#PCDATAとして出力するケースが抜けていますね。「比較的安全なタグ属性」というのが何なのか分かりにくいですし……本当にこういう表現だったのかなぁ。
ともあれ具体的な対応としては、こんな感じの想定なのですかね。
- 「比較的安全なタグ属性」……属性値を動的生成する場合、属性値を必ず二重引用符で括り、" と & と < をエスケープする。
- 「タグのURL属性」……href属性など URL を値とする属性値においては、上記の対応に加え、属性値が javascript: などで始まることがないように注意する。ユーザが URL を入力するような場合は、http:// か https:// で始まることを確認し、そうでない場合はエラーにする事が望ましい。
- 「タグのstyle属性、イベントハンドラ属性、scriptタグの内側」…… スタイルシートやスクリプトとして解析されるような値を動的生成することは、できるだけ避ける。どうしても動的生成する必要がある場合には、任意のスクリプトが実行されることがないように細心の注意を払う。
付け加えると、以下のようなものがあります。
- #PCDATA …… & と < をエスケープする。
- 注釈宣言 …… 通常、注釈宣言の内容を動的生成する必要はないと思われる。動的生成する場合は -- が出現しないようにする必要があるが、エスケープする方法はない。
- CDATA区間 …… 動的生成する場合は ]]> が出現しないようにする必要があるが、エスケープする方法はない。
- 内容モデルがCDATAである要素の内容 …… script要素、style要素については前述のように、極力動的生成しないようにする。その他の要素についても、原則使わない。使うときは </ が出現しないようにする必要があるが、エスケープする方法はない。
最後の奴らはほとんど必要ないですけどね。
こういうのはどこかにまとめておくと良いのかなぁ。
「特に後者の2種類が危険なタグ。最近は、Ajaxでscriptタグの内側にIDを埋め込むこともあるが、これは聞いただけで緊張感の増す実装なのである」(同氏)。
「Ajaxでscriptタグの内側にIDを埋め込む」なんてことはたぶん誰もしないので、これは「script要素の中でIDなどを動的生成する機会が増えた」ということが言いたいのではないかと思います。私は緊張に耐えられず過剰エスケープしていますけれど。
3つ目が、入力パラメータに悪意のパターンを仕組んでサーバーに注入・侵害する「入力問題」。SQLインジェクションはここに分類され、ほかにもコマンド/LDAP/XPATH/SSIインジェクションなどが含まれる。この問題の原因は、Webアプリケーション側で悪意の入力を排除できていないことだ。
予防的実装例としては、特殊な文字列を制限することが重要で、SQLインジェクションならば、「'(シングルクォート)」「\(バックスラッシュ)」「;(セミコロン)」などのエスケープが必須だが、加えてシングルクォートの内側と外側など文脈に応じた対策を行うほか、プリペアド・ステートメントを使用するのもよいという。
入力の排除、入力の制限ですか? 基本的にはエスケープすれば良いだけだと思いますが……。SQLインジェクションの対策としては、エスケープよりも「プリペアド・ステートメントを使用する」のほうが先でしょうね。
例えば、単純にCookieにセッションIDを格納するだけの実装では、盗むのもたやすい。
たやすいですかね? 確かにXSSがあればたやすいのですが、他の脆弱性がなければ難しいと思うのですけどね。
しかし、本当にたやすく盗まれるのだとすると、どういう対策をしたら良いのでしょう。Cookieを使わずにとなると、携帯サイトのようにURLにつけたりする事になると思いますが、それはもっと危険だと思いますし……。
また、わざわざ盗むまでもなく、攻撃者が用意したセッションIDを正規ユーザーに意図せず利用させる「セッションフィクセーション(セッションIDのお膳立て)」という手口もある。もしもセッションIDの値が固定だとすると、正規ユーザーがWebサイトにログインしたあとに、攻撃者も同じセッションIDを使って簡単に正規ユーザーになりすますことができてしまう。
セッション固定攻撃は、攻撃者がターゲットのセッションIDを固定させる攻撃であって、最初からセッションIDの値が固定なのではないと思いますけれど。まあ、最初から固定だったらもっとマズイですね。
- 「Webアプリ脆弱性分類とか」へのコメント (4件)
- 前(古い): 森の生活 49日目: きんのジョウロ
- 次(新しい): IPAのSecurity RSSポータル