2009年12月16日

知らなかったらNGなWEBアプリケーション脆弱性一覧

先日、AmebaなうがCSRFという非常にポピュラーな脆弱性を披露したかと思ったら、ここ数日はセブンネットショッピングでXSSの脆弱性と、ID推測による他ユーザの個人情報閲覧の問題が発生しているという噂が流れています。

ユーザの情報を預かっておきながら、基本的なセキュリティの対策もできていないというのは、銀行に例えるなら、お金を預けようとした時に「お金は預かります。ちゃんと保管します。でも警備はあまりしないので盗まれたらスイマセン」と言われるようなものだと思う。

警備に穴があったというのではなく、まともに警備してませんでした、というのはさすがにありえないことです。


そこで、野良WEBプログラマである私が知っている脆弱性を列挙してみた。

私はプログラマであってセキュリティの専門家ではないです。しかも今年の春辺りからずっと外向けのWEBプログラムは組んでません。

その人間が知っているものを並べただけの項目なので、これをすれば全てというわけではないです。

この情報の利用用途は、「皆さん、これを見てセキュリティを意識しましょう」ということではなく、「もし、あなたの会社のセキュリティ担当が、ここにある脆弱性の中に1つでも認識していなかいものがあって、且つ、外部に公開されたWEBサイトを運営していたとしたら、神に祈ってビタミンを採ってから、ある程度の支出を覚悟した上で専門家を呼んで対策をしてください」というものです。


これからセキュリティの勉強をされたい方は、こちらのサイト辺りがオススメです。

IPAセキュア・プログラミング講座
http://www.ipa.go.jp/security/awareness/vendor/programmingv2/web.html

2009年度IPA情報セキュリティセミナー技術コース標準編
http://www.ipa.go.jp/security/event/2009/isec-semi/documents/2009tech1_v2.pdf

Webアプリにおける11の脆弱性の常識と対策 - @IT
http://www.atmarkit.co.jp/fjava/rensai4/webjousiki11/webjousiki11_1.html

というわけで、その辺のWEBプログラマが知っている脆弱性一覧は以下。



1. SQLインジェクション

情報漏えい、WEBページの改ざんによるユーザ被害(アクセスしてきたユーザ全員をマルウェア満載のサイトにすっ飛ばすとか)などが発生しうる。

自前でシングルコーテーションを置換しているだけだと、DBMS個別の仕様によって抜けが発生することもあるので、PreparedStatement的な何かを利用しておくことがオススメされる。



2. OSコマンドインジェクション

ユーザ入力を元に、system関数などを使ってOSコマンドを発行する際などに発生する。

パイプで繋げて任意のコマンドを実行させられる可能性もある。wgetとのコンボ攻撃が成功したら、サーバが乗っ取られる可能性もある。

発生した場合の危険性は、おそらく最悪なレベル。チェックしなければいけない記号の数が多いので抜けが出ることも。



3. 公開領域へのファイルの配置

リンクを貼ってなくても、公開領域に置いておいたらそこにある情報は閲覧される可能性があります。大丈夫とか思わないでください。顧客の名簿を誤って公開領域に置いていたらいつの間にかWinnyで流れていたとか、良く聞く話ですから。

スクリプトのバックアップファイルを公開領域に置いてしまってソースの中身を見られて、そこで見つけた脆弱性を攻撃されるなどのパターンも。



4. ディレクトリトラバーサル

閲覧するファイルのパスをユーザに指定させる際に、「../」って打つと上の階層が見えてしまうなんていう状況を放置しておくと発生する。

この手の脆弱性があれば公開領域に置いてない情報が漏れる可能性もある。それどころかサーバに置いてあるファイル全てが閲覧される危険性がある。



5. パラメータ推測

「hello.html?id=101」などのパラメータが入っていた場合に、ユーザは「id=102」と打ったらどうなるのだろうと考えるものである。

そういった安易な考えで発行したURLで、他人の個人情報が見れてしまうようなシステムが昔はけっこうあった。

最近はスクリプトを使った総当たり攻撃が海外から来るので、推測出来なくても「数打てば個人情報が抜ける」というレベルでも危ない。「1万リクエスト打って1つヒットするかどうか」というレベルでも、向こうは平気で1日数百万のリクエストをIP変えながら打って来る。

十分に安全だという可能性を考慮する際は、誕生日パラドックスもお忘れなく。



6. クロスサイトスクリプティング(XSS)

POSTされたデータやクエリストリング、Cookieなどの情報をページにリダイレクトする際に、そこにコードを混ぜ込むことで任意のスクリプトを実行させる攻撃。

1〜5の脆弱性に比べると発生条件に一手間かかるが、決まればいろんなことが出来るので危険なことに変わりはない。

セッションIDが盗難されて本人になりすまして買い物バンバンされるとか、ページ改ざんによって偽の情報を表示されるとか、そっくりの偽ページに飛ばされてパスワード入力を求められるとか。



7. クロスサイトリクエストフォージェリ(CSRF)

Amebaなうの場合は、リンクをクリックするだけで勝手に投稿やフォローなどが実行されていた。

スクリプトや画像タグ、iFrameなどを利用して、罠ページを開くだけでユーザが自覚症状のないうちに攻撃が実行することも可能。

有名なのがはまちちゃんだからまだ良いが、ショッピングサイトで同様の脆弱性があった場合は、ユーザが意図しな買い物をしてしまう可能性もある。シチュエーションによっては侮れない。



8. エラーの詳細が表示されてしまうエラー画面

エラーが発生した際に、ソースのこの部分でこういうエラーが発生しましたよという情報を表示させてしまうと、攻撃の手がかりを相手に与えてしまうことになる。

SQLインジェクションを使用して手探りで攻撃を成功させるのは根性がいるが、エラー画面にSQLの一部が表示されれば試行回数をぐっと少なくして攻撃できる。

デフォルトだとエラー内容を出してしまう設定になっている場合が多いので、必ずカスタムエラー画面等を用意して、エラーの詳細がエラー画面から類推されないようにする。



9. デバッグモード

開発時に、パラメータに「debug=1」と入力すると、デバッグ文が画面に表示されるとかいう機能を組み込んでおいたりすることがあると思いますが、本番になった時に無効にし忘れることがある。

デバッグ情報は攻撃者にとって有用な情報になる場合もありますし、デバッグ文自体が情報漏えいしていたり、それを利用するとXSSが成立するなどのパターンも考えられます。



10. Cookieの改ざん

知り合いに脆弱性のチェックを頼まれた時に、この点を攻撃するとよく成功します。入力パラメータはチェックしても、Cookieの値をいじってリクエストした場合についてはちゃんとテストしていない場合が多いようで。

Cookieの値を利用してSQLを生成していればSQLインジェクションが発生しやすいポイントになりますし、値をちょっと変えたら他のユーザとしてログインできてしまったなんてこともあります。



11. ヌルバイト文字列

POSTする場合は0x00を、GETの場合はパラメータに%00などを埋め込むと、相手の環境によっては文字列の終端を勘違いして予想外の挙動をしてしまう場合がある。



12. HTTPレスポンススプリッティング

HTTPのヘッダ情報をユーザ入力を元に操作する場合に発生することがある。ユーザ入力を元にLocationでredirect設定する時に発生しやすい。

改行コードを混ぜて不正なレスポンスを作り出すことで、プロキシサーバのキャッシュに任意の内容を埋め込むことが可能になったりする。



13. UTF-8エンコーディング

UTF-8は同一の文字を複数のコードで保持している場合があるので、例えばバックスラッシュをUTF-8の状態で対策したつもりになっていても、別の文字コードに変換したらバックスラッシュが残ってしまっていたというような事象が発生しうる。

なので、途中で文字コードの変換が発生する場合は、変換をしてから入力チェックをする必要がある。特にDBとHTMLの文字コードが違う場合などは注意。



14. DNSキャッシュポイズニング

DNSサーバの脆弱性を突いた攻撃で、リクエストしたURLが飛ぶべき本来のIPとは別のIPに飛ばされる。

WEBプログラマには直接の対策はできないけど、注意を喚起するとかアナウンス面ではやれることはなくもない。

あと、一時期あれだけニュースになっていたことなので、もし知らなかったら「セキュリティの情報に興味のない人」と思われるかもしれない。



15. メールフォームのスパム化

宛先や本文を自由に設定してメールを送信できる機能を置いておくと、いつの間にかスパム業者が押し寄せてきて1日に何万通もメールを送信して行くことがある。

「この記事を紹介する」とか「この商品を紹介する」のようなメール送信機能を作成する場合は、スパム業者が利用し辛いように、「設定できる文面の制限」、「指定できる宛先の制限」、「1日に送信できる件数制限」などを入れておくことが推奨される。




以上、野良プログラマが知っている脆弱性一覧でした。

繰り返しますが、これはプログラマレベルの知識です。このレベルでは確実にセキュアなサイトを作れるものではありません。

そんなレベルの対策が、十分なユーザ数がいるサービスでされていなかったというニュースを見ると、ちょっと怖いなぁと思ってしまいます。




修正履歴

2009/12/24 (Xmas=クロスメディアアーカイブスクリプティングの日に修正)

いろいろ表現が変なところを微調整。

CSRFとXSRFの両方の表記が混ざっていた為、CSRFで統一。

CSRFの実行でクリックしなくてもスクリプトとかで打たれるという話を追記。

エロい人が勝手に書き換えられるように、クリエイティブコモンズにする。

メールフォームのスパム化を追加。昔、知り合いのサイトが食らってた。

セッション周りも書こうと思ったのだけど、ハイジャック、リプレイ、フィクセーションといろいろあって書くのが面倒だったので保留。


Creative Commons License
知らなかったらNGなWEBアプリケーション脆弱性一覧 is licensed under a Creative Commons 表示 2.1 日本 License.