Web アプリケーションのセキュリティ

参考:PHP サイバーテロの技法 攻撃と防御の実際 GIJOE著

基本事項

フォームデータ

フォームデータは、「 HTML Form での記述に関わらず、多様な形で送られる」という事に注意する。

  • HTML Form は、「ユーザビリティ」の為に構築する物
  • フォームデータ(HTTP Request) を受け取る際の処理は、セキュリティ保持が目的

DocumentRoot

HTTP アクセスによって公開されるディレクトリの頂点が DocumentRoot 。

  • DocumentRoot 以下にインクルードファイルが存在する場合、ファイルの先頭に防御コードを入れる
  • .htaccess を利用して、インクルードファイルを Deny に設定する
  • 可能な限り、実行ファイル(ユーザアクセスファイル)以外は DocumentRoot 外部に置く

エラー制御と Path Disclosure

PHP のエラーレポート機能によって、ファイルのパスが表示される事がある。

  • “display_errors off” として、エラーを STDOUT に出力しない
  • error_reporting の設定で出力情報を制御した場合、必要な情報までも失う事に注意
  • “log_errors on” として、ログファイルに出力して情報喪失を防ぐ

PHP5 から E_STRICT というエラーレベルが利用できるが、PEAR ライブラリなどでこれに対応していない物がある事に注意する。

ホワイトリスト法とブラックリスト法

ブラックリスト法は、想定外の状況には対応できない。

  • ブラックリスト法:任意の禁止パターンを発見次第、不正検知
  • ホワイトリスト法:任意の許可パターン以外を発見次第、不正検知

画像ファイルのアップローダを考えると、明示的に許可する拡張子を設定しておく方(ホワイトリスト法)が無難。

不正検知時の対応

不正が検知された場合の対応方針。

  1. 強制終了
  2. 無害化して続行

受動的な攻撃の場合は 2 、それ以外では 1 が推奨される。

明確な意志を持った攻撃がなされた場合に生じる問題に対しては、完全に対処出来る保証がないため、処理を強制終了させる事が望ましい。

パスワードクラック

Brute Force Attack によるクラックを考慮して、半角英数字のみの場合パスワードは最低 6 文字以上は必要。

また、パケットスニファによる盗聴を考慮して、SSL を導入する事も有効。

SSL の効果

SSL は「Web アプリケーションを安全にするもの」とイコールではなく、「通信傍受によるクラッキングへの対策に有効」だと理解する事。

近頃の環境を考慮した場合、パケットを傍受しようとした場合、通信系路上にあるルータやサーバを直に乗っ取る必要が出てくる。Web アプリケーションを作る際に、このレベルでのクラッキング可能性を考慮する事はナンセンスであると言える。

利用者側に与える安心感は大切でも、開発者側まで同じ感情を持ってはいけない。

DoS アタック

Denial of Service(大量アクセスによってサーバ/ネットワークを飽和状態にする事)。

低レイヤ層からの攻撃だけでなく、ブラウザリロードによる攻撃も深刻な影響を与える。攻撃である可能性がある事を検知して、Deny 対象に加えるなどの対策が必要。httpd の段階で処理が中断される事だけでも負担軽減につながる。Web アプリケーションレベルでの対策を考えた場合、DocumentRoot 内のファイルに対して HTTP サーバからの書き込みを許す事になるため、iptables などを利用して TCP 層でシャットアウトする仕掛けがより効果的。

投稿の修飾機能

フォーラム系アプリケーションなどで、HTML タグを許可する場合の無害化対策は重要。

  • HTML 再構築法
  • HTML 形式で投稿されたテキストをパースして、安全なタグ/属性のみで構築し直す方法
    • メリット:既存の JavaScript による WYSIWYG エディタを利用可能
    • デメリット:実装が困難で、抜けの可能性を否定できない
  • 独自タグシステム構築
    • HTML とは異なる独自の記法を構築する
    • メリット:サニタイズ前のテキストをそのまま表示したとしても被害は少なく、実装次第で豊富な表現が可能
    • デメリット:新しい記法の学習をユーザに強いる

strip_tags 関数によるタグ除去法を利用した場合、修飾タグに差し込まれた属性による Script Insertion には対応できない。

HTML による投稿の場合、HTML 再構築法を利用する事が安全を確保する上で重要。

外部画像

外部画像に対して表示許可を与えた場合に何が起きるか。

  • 画像があるサーバに残すログ
    • セッションハイジャック対策に利用される User-Agent などが漏洩する
  • 拡張子による実態偽装
    • サーバ設定次第で、.jpg ファイルへのアクセスで PHP(任意のスクリプト) を実行する事が可能

CSRF 対策として、「重要な操作は POST のみ」や「リファラチェック挿入」などを導入する事で、Location ヘッダによる攻撃を防ぐ事は可能。

Flash を許可する事は絶対にしない。外部 Flash を許可する事は、ユーザ任意の JavaScript 実行を許可する事と同義と考える。

PHP セッション

PHP セッションに関する実行時設定

PHP セッションは、鍵を盗まれた時点でその鍵と紐付けられたセッションが乗っ取られる事に注意。

  • セッション名を変更する
    • session.name/session_name() によって指定するセッション名はデフォルトで PHPSESSID
    • 一部の自動攻撃をさける意味では効果的
  • 「セッション固定」対策として、session.referer_check を指定する
    • リファラが外部からを意味する場合に GET からのセッション鍵登録を行わない
    • そもそも GET からセッション鍵を指定できる事が問題
  • 透過的なセッション ID 機能(session.use_trans_sid)を off にする
    • Cookie が利用できない場合、ページ内のあらゆる相対リンクにセッション鍵が埋め込まれてしまう問題がある
  • セッション鍵の検出を Cookie からのみ行う(session.use_only_cookies = 1)
    • 「セッション鍵保存先にCookie が利用可能」を意味する session.use_cookies はデフォルトで 1(有効)
    • 「セッション鍵保存先はCookie のみ」を意味する session.use_only_cookies はデフォルトで 0(無効)
    • 一部ブラウザや i-mode での利用を制限する事にはなるが、現実にはあまり考慮する必要がない(i-mode 向け設定は必要)

セッション関連の対応策をコーディングするために、”session.auto_start off” が推奨される。

セッションを利用した XSS と HTTP レスポンス分割

PHP5.0.4 や 4.3.11 では、セッション鍵に改行を含める事で、容易に XSS や HTTP レスポンス分割攻撃が可能になる。

session_start() を実行する前に、必ずセッション鍵の整合性を確認する必要がある。

SSL 利用時のセッション鍵の取り扱い

セキュアフラグを立てた Cookie を利用する場合、HTTPS/HTTP 間でのセッション継続を行う事は出来ない。

セッション2つを使い分ける方法が一般的。

HTTP 側から HTTPS 側にセッションデータを引き継ぐ場合、HTTP からのリクエストでセッション鍵を受け取り、その鍵と紐づけられたセッションファイルのデータを利用する(session.save_path で設定されたディレクトリにある sess_セッション鍵の内容を unserialize() する)。この場合、session_start() 前に “ini_set(’session.cookie_secure’, 1);” としてセキュアフラグを立てておく。

セッション鍵の変更

XSS 脆弱性やネットワーク盗聴によるセッションは胃弱の可能性は常に存在する。

  • session_regeneratre_id() の効果
    • 新しいセッション鍵の発行
    • セッションデータを新しいセッション鍵に紐づける
    • 新しいセッション鍵を含んだ Set-Cookie HTTP レスポンスヘッダの出力

session_regenerate_id() を利用すると、Set-Cookie ヘッダが2回出力される。この場合、最後に発行されたセッション鍵によって上書きされ、次回アクセス時にブラウザが新しいセッション鍵を送るようになる。ただし、データが残ったままなため、次回アクセス時に古いセッションデータを明示的に削除する必要がある。バージョン 5.1 以降であれば、session_regenerate_id(true) とする事で、自動的に古いセッションデータは削除される。

データステータス

データステータスとは

データは状況によって様々な状態を持つ。

PHP の場合、文字型と整数型で異なる実態間にイコール関係が成立する場合がある。 if (”” == 0) {} 上記の条件式は成立する。これは、この場合の比較に置いて”“が自動的に 0 という整数型に自動キャストされるために起きる実装。

「用途」というステータス

処理の流れの中で扱うデータは、明示的に目的にそった命名(利用)が必要。

ファイル名の文字列を扱う場合に、その文字列をファイル処理に利用するのか、テキスト表示に利用するのかによって行うべき処理は異なる。

HTML 出力用サニタイズの注意点

出力する部分の HTML 構造によって、必要になるサニタイズ方法は異なる。

  • <p>$text4html</p>
  • <input type=”text” value=”$text4html” />

後者の場合、”$text4html = strip_tags($text);” でなく、”$test4html = htmlspecialchars($text, ENT_QUOTES);”をりようしなくてはならない。strip_tags() ではクォーテーション文字は素通りするため、予期しない文字列を挿入される危険性が生じてしまう。

 
koshigoewiki/php/security/web_アプリケーションのセキュリティ.txt · 最終更新: 2006/03/03 01:33 by koshigoebushou
 
Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki