Web アプリのセキュリティ限界に迫る (国分 裕)

セキュリティを確保する方法には「構築」「検査」「防御」「検知」とあるが、それぞれの項目についてあまり成熟していない。
ではどうすればいいのかを解説。


解説編

  • Web の推移
    1. Hyper Text を転送する方法として作られる。すべて制的コンテンツ (誰がアクセスしても毎回同じ URL)。認証方式としてもせいぜい Basic 認証などを使っていただけ。
    2. アクセスする回数、人、アクセス権の制御を細かく設定したい! という要望が発生した
    3. 動的コンテンツの転送の仕組み (CGI からサーブレット等のサーバー側でアプリケーションを実行する、など) が出来上がる
  • Web アプリケーションとは
    • クライアントとの通信に HTML を使用した仕組み。
    • 構成要素
  • 個別アプリケーションの問題
    • インターネットに公開されており、短い開発期間、限られた予算で作られている。
      • 発注者側がセキュリティ意識を認識していない
    • セキュリティ上のスキルが欠如もしくは認識していない人が開発している
      • 受注者側がセキュリティ意識を認識していない
  • Web アプリケーションに潜む脆弱性
    • SQL Injection
      • 定外の SQL 文を発行されてしまう脆弱性
        ログイン ユーザーを偽証できてしまう
        データを新しく追加・変更・削除してしまう
    • Directory Traversal
    • などなど

構築編 (セキュアなアプリケーションを構築しましょう)

  • 設計上の留意点
    • 入出力データの定義
      • 文字種と形式、長さ
        パラメータとして使える文字、長さを洗い出す。
      • どこからどこにデータが渡るのか
      • データの意味
        数字の羅列がセッション ID なのか、郵便番号なのか・・・。
      • 可変か固定か
        誰がアクセスしてきても同じ値なのか、人ごと、アクセスするタイミングごとに違うのか。固定のものなら、それをアプリケーションに組み込む必要があるのかどうか。
      • HTTPS で保護するデータかどうか
        個人情報か、個人が特定できるパラメータが含まれているか。
    • 画面の遷移
      • エラーが出たらどういう画面がでるか
    • プログラム開発が始まってからでもいいので、しっかり設計する
    • でないとプログラムのバージョンアップ、改造ができない
  • プログラミング上の留意点
    • 入力値のチェック
      • 設計に従い正しい値が入力されているか確認する
        正規表現を使用すると簡単である
        これだけでもかなり硬いものが出来上がる
    • サニタイジング
      • 入力チェックを潜り抜けるものが必ずある
        <>などは、そのせいでCrosssite Scripting が発生したり。
      • 出力で特殊文字を無効化する
      • CSV の場合
        , は "" でくくる。
        " は全体を "" でくくり、" を "" に変換する。
        改行は "" でくくる。
      • HTML、SQL、OS コマンド・・・
        自分で仕様書読んで考えなさい!
  • まとめ
    • 設計をしっかりする
    • 入力チェックとサイニタイジングをしっかりする
      9 割以上はこれに失敗している
    • バグ、ミスをできるだけ排除する
      一言で書くととっても簡単なんだけど・・・。
      これを可能な限り排除しよう

検査編 (設計上のミスを見つける、バグ、ミスを減らす。)

  • 検査とは
    • 要求された機能がちゃんと動くかどうかはちゃんとチェックするでしょう。
    • 問題となるような妙な入力がされた場合に、どういった挙動を示すかどうか、といったチェックがもれている。
    • 設計書の段階で、プログラミングの段階で、ブラックボックスとして実際動かしてみて、擬似攻撃を行ってそれぞれ確認する。
  • 検査手法
    • 設計書を見ながら、正しいとされる値以外のものを入力する。
      数字 4 字なら、4 桁以上の数字、負の数字、英文字、2 バイト文字を入力する・・・。
      エラー処理がきちんと行われるかどうか。
      セッション ID に -1 を入力したら、前の人のセッション ID が見えてしまった・・とか。
    • 特殊文字を入力
      !"#$%&'()=
      お勧めは ' (シングルクォート)
      %00、%0D (改行コード)、%DA (改行コード)
      HTTP ヘッダやクッキーを出力するときにこういった文字が入ると、妙な画面が表示される。
  • 検査を楽にするツール
    • Burp Proxy
      • HTTP のリクエストを奪い取って書き換えるツール。
      • アキレスは昔紹介してたけど、不安定で使いにくいらしい。
  • 私が検査中に考えること
    • それを作った人はどれだけのスキルを持っているのか
    • どういったプログラムが動いているのか
    • どういう動きを期待しているのか
    • どういう書き方をしているのか
    • ミスをしそうな箇所というのがある程度あるので、典型的なところから、スキルレベルから失敗しそうなところを探したり。
    • ひとつのシステムを複数のベンダーで作っていると
    • 入り口はクロスサイト山ほどあった。
    • ショッピングはまったくぜんぜん見つからない
      (多分作ってる人がぜんぜん違うんじゃないかなぁ)
    • このふたつをつなぐところはぼろぼろだったり・・・。
    • アプリケーションがどう動くかよりも、それを作った人はどういう人なのか、そういったところを見る。プログラムだけ見ていても見落とす。
    • 数こなしていかないとなかなか見えないところかも。
    • 同僚なんかで、この辺ミスしそうだなぁ、というところを注意してみてみるといいかも。
  • 自動検査ツール
    • AppScan
    • ScanDo
    • WebInspect
      • セッション管理周りの問題をまともに見つけられない
    • WebProbe
      • セッション管理のしかたに問題が無いか検査するのに特化したツール
    • これらのものを併用して使うことになる
    • AppScan はそれなりに検索してくれる
    • ScanDo はアプリケーションに password という文字列があるだけで、SQL Injection があるというエラーが出てきてしまう。これは「おや?」と思うでしょう
  • 自動検査 VS 手動検査
    • 自動検査ツールの場合
      • 早い
      • 操作する人がどこを注目しているかにもよるけど、人に依存しない
      • 検査ツールが持っている決まったシグネチャしか検査しないので検査してくれないものもある。
    • 手動検査ツールの場合
      • アプリケーションの持っている挙動から、いろいろ検査できるので、さらに深く調べられる。
      • ブラウザでアクセスできる範囲はどこでも。
      • 人が手足を動かすので、手間がかかる。時間がかかる。検査の費用もかさむ。
      • スキルレベルによる差も出てくる。
      • 手順書で統一できる範囲は、決まったことなので自動検査ツールでもできてしまう。
      • 感じ取るセンスが検査する人によって違うので。。。
  • まとめ
    • 早い段階で検査を。見つけたらすぐ修復しないと、設計に問題があったら手遅れに・・・。
    • 検査ツールもいいけど、それで見つけられない問題もある。
      自動検査と手動検査のすみわけを行おう。
    • ツールを使って定期検査、大規模な検査を行なう。
      重要なサイトに絞って、手動検査を行なう。
      こういった検査方法を併用する・・・。

防御編

  • Application Firewall
    • mod_security
    • guard3
      • IIS に組み込む
      • これもパターンマッチングする
      • レジストリに設定を入れる
    • Guardian@JUMPERZ.NET
      • Web サーバーの一戸前にアプリケーションをおいて、保護するリバース プロキシ
      • JAVA でかかれているので、どういったサーバーでも JRE が入っていれば動作する
      • ルールはかなり細かく書くことができる
    • AppShield
      • リバースプロキシ
      • 基本はすべて拒否 (ほかのものは基本はすべて許可)
      • Web ページはたくさんある、それをひとつひとつ設計していかなければならないわけではない
      • 勝手に Web ページを読んで、勝手にルールを作ってくれる。
      • 設定、運用は大変。値段も高い。
      • ひとつの Web サーバーを守るのに、Web サーバーと同じくらいのサーバーが必要。
        アプリも200〜300万かかる。Web サーバーの台数分用意しなければならない。
      • ワームを防ぐのにも十分活用できる
  • 不振なアクセスの特徴
    • 特殊な文字が含まれている。
    • 2xx、3xx 以外のリターンコード
  • 防御できない攻撃
    • 特殊文字を使わない攻撃、リターンコードが200の攻撃
  • まとめ
    • 特殊文字を防ぐだけで攻撃は防げる (が、パターンマッチングだけでは防ぎきれない)
    • AppShield はかなり堅いが高い

検知編

  • 検知といえば IDS
    • IDS では検知しきれない
      • Web アプリケーションへの攻撃は、目的が管理者権限の奪取だけとは限らない
      • 決まったパターンだけの攻撃ではない。みんながおんなじ攻撃手法を使うから検知できるのであって、個別のアプリケーションの数だけ、攻撃手法がある。
      • SSL で暗号化されるとお手上げ
  • 検知方法
    • 特殊文字を含んだアクセスを攻撃とみなす (たくさんのアラートが送信されるだろう)
    • エラーコードを含んだアクセスをアラートとする (404 は山ほど発生するので、管理者が耐えられないし)
    • ログから探す → IDS から検知させるのはあきらめる。
    • 検索方法は SQL 文を書くようにできる
      • 特殊文字を含んだアクセス
      • エラーを頻発させるユーザーリスト
      • 特定ユーザーの同じ URL へのアクセス
    • CSV で出力、Excel で解析・・・
  • まだ見つけられない攻撃
    • POSTメソッドを使用していると、HTTP リクエスト丸ごと保存しておかなければならない・・・。
    • アクセス件数が少ないと、リストに出てこないから見逃す。
    • Session Hijack されると、どうしようもない・・・。
    • すべての HTTP リクエストを保存しておいても、判断できない。
  • まとめ
    • 簡単に見つかるものと、簡単に見つけられないものがある
    • 手間と時間とお金をかけて見つける価値があるのかどうか判断。
    • 絶対に見つけられない攻撃もある。

まとめ

  • 脆弱なアプリケーションは守りきれない
  • 攻撃を事後に見つけるのも困難
  • 設計、プログラミング、テストの段階でSecurity を意識した構築を。
  • おまけ
    • 対策を施さない選択肢もある
      • リスクが低い場合、リスクがほかのものでカバーできる場合 (そんな場合あるんかしら?)
    • 開発側の自己防御
      • 対策を施さないリスクを十分説明する
      • 責任は権限のある人