目次 1 はじめに 3 1. 1 本書の目的 3 1. 2 セキュリティ ホールの一生 5 1. 2. 1 フルディスクロージャという思想 6 1. 3 セキュリティの階層 8 2 HTTP 通信の基礎 21 2. 1 Web アプリケーションとネットワーク 21 2. 2 階層化されている通信プロトコル 22 2. 3 HTTP 26 2. 4 パケットキャプチャによって 実際に確認する 27 2. 5 パケットキャプチャから見た GET と POST の違いを実際に確認する 35 2. 6 クライアント側の入力制限とセキュリティ 38 2. 6. 1 クライアント側の入力制限はセキュリティ対策ではない 38 2. 6. 2 名前 をデータとして使う場合のセキュリティ対策忘れに注意 39 2. 7 CGI プログラムから見た GET と POST の違い 39 2. 8 クエリ文字列と Referer 情報による漏洩 41 2. 8. 1 クエリ文字列と Referer 情報による漏洩 41 2. 8. 2 クエリ文字列を外部 Web サイトに漏洩させない方法 42 3 HTTP セッション管理となりすまし 46 3. 1 HTTP はステートレスなプロトコル 46 3. 2 HTTP セッション管理機能の歴史的経緯 47 3. 2. 1 HTTP セッション管理機能の歴史的経緯 47 3. 2. 2 REMOTE_ADDR を使う ( 非推奨 ) 48 3. 2. 3 ログと IP アドレス 49 3. 2. 4 TOR( 蛇足 : ログと IP アドレス ) 50 11 目次.indd 11 08.3.24 6:09:31 PM
3. 2. 5 HTTP_Referer を使う ( 非推奨 ) 51 3. 2. 6 Hidden クエリや Cookie 情報にデータを保持させる ( 非推奨 ) 52 3. 3 セッション ID によるセッション管理 53 3. 3. 1 セッション ID によるセッション管理 ( 現在の主流 ) 53 3. 4 既存のセッション管理機能 55 3. 4. 1 既存のセッション管理機能を使う 55 3. 4. 2 既存のセッション管理機能を使う上での注意点 ( セッション タイムアウト値 ) 56 3. 4. 3 AJAX と最小タイムアウト値 ( 蛇足 ) 57 3. 4. 4 既存のセッション管理機能を使う上での注意点 ( 明示的なセッション破棄ページ )58 3. 5 Session Fixation( セッション固定化攻撃 ) 58 3. 5. 1 Session Fixation( セッション固定化攻撃 ) 58 3. 5. 2 ブラウザが提示したセッション ID をそのまま採用する Web アプリケーション サーバ 60 3. 5. 3 セッション ID をクエリ文字列で保持する Web アプリケーション サーバ 63 3. 5. 4 常時 セッション ID を提示してくれる Web アプリケーション サーバ 64 3. 5. 5 Cookie Monster (CrossDomain Cookie Injection) 65 3. 6 セッション ID の安全性 66 3. 6. 1 推測困難なセッション ID を盗み出す Cross-Site Scripting 攻撃 66 3. 6. 2 セッション ID には推測困難性が必須 66 3. 7 ワンタイムなセッション ID 68 3. 7. 1 ワンタイムなセッション ID 68 3. 7. 2 ワンタイムなセッション ID を使う上での注意点 69 3. 8 セッション ID の分散 70 3. 8. 1 セッション ID の分散 70 3. 8. 2 既存と自作にセッション ID を分散させる 71 3. 9 改ざん検知ハッシュ値と HMAC という考え方 72 3. 9. 1 単純な改ざん検知ハッシュ値は危険 72 3. 9. 2 HMAC という考え方 75 4 CSRF とアクセス制御 77 4. 1 CSRF( クロスサイト リクエスト フォージェリ ) 77 4. 1. 1 CSRF(Cross-Site Request Forgeries) 77 12 目次.indd 12 08.3.24 6:09:31 PM
4. 1. 2 CSRF 攻撃の対策 ( 推測困難なトークンとパスワードの再入力 ) 79 4. 1. 3 CSRF 攻撃のトークンとセッション ID 81 4. 1. 4 フレームワークに実装している CSRF 攻撃対策機能を使おう 83 4. 1. 5 CSRF 攻撃の対象となる Web ブラウザの機能 83 4. 2 アクセス制御 84 4. 3 静的コンテンツへのアクセス制御 89 5 メモリ破壊バグとその対策 91 5. 1 メモリ破壊バグとは 91 5. 2 バッファ オーバーフロー 92 5. 2. 1 スタック領域におけるバッファ オーバーフロー 93 5. 2. 2 たった 1byte のバッファ オーバーフローで制御を奪うことは可能か? 98 5. 2. 3 ヒープ領域におけるバッファ オーバーフロー 101 5. 2. 4 malloc chunk corruption ( ヒープ領域におけるバッファ オーバーフ ローの一例 ) 101 5. 3 バッファ オーバーフローの対策 103 5. 4 バッファ オーバーフローの対策の注意点 106 5. 4. 1 バッファ オーバーフロー バグを発生させやすい 注意すべき関数 106 5. 4. 2 終端文字の問題 107 5. 4. 3 コンパイル オプションの問題 110 5. 4. 4 バッファ アンダーフロー 111 5. 5 Integer オーバーフロー 111 5. 6 フォーマットストリング バグ 116 5. 7 フォーマットストリング バグへの対策 119 5. 8 メモリ破壊バグのまとめ 120 6 インジェクション系セキュリティ ホールとその対策 122 6. 1 はじめに 122 6. 1. 1 最初に結論を書いてみた 122 6. 1. 2 エスケープ処理がインジェクション系セキュリティ ホールへの基本対策 124 6. 1. 3 攻撃者が操作できないデータのエスケープの必要性 125 13 目次.indd 13 08.3.24 6:09:32 PM
6. 1. 4 バリデート + エスケープ = サニタイズ 126 6. 1. 5 エスケープ処理はどの時点で行うべきか 128 6. 1. 6 まとめ 133 6. 2 XSS(Cross-Site Scripting) 133 6. 2. 1 XSS(Cross-Site Scripting) の概略 133 6. 2. 2 XSS(Cross-Site Scripting) の実例 137 6. 2. 3 XSS(Cross-Site Scripting)= 掲示板攻撃 141 6. 2. 4 XSS(Cross-Site Scripting) により想定される被害例 142 6. 2. 5 XSS(Cross-Site Scripting) 対策の基本 148 6. 2. 6 XSS(Cross-Site Scripting) 対策で使える HTML エンコード関数 149 6. 2. 7 XSS(Cross-Site Scripting) 対策で使える Web アプリケーションの機能 150 6. 2. 8 注意したい XSS(Cross-Site Scripting) の対策漏れ 155 6. 2. 9 XSS(Cross-Site Scripting) の対策 JavaScript の一部として使う場合 159 6. 2. 10 特殊な XSS の実例 167 6. 3 SSI インジェクション 169 6. 4 文字のエスケープと文字列の監視 174 6. 5 スクリプトのコメント 177 6. 6 OS Command インジェクション 178 6. 6. 1 OS Command( 外部コマンド ) とは 178 6. 6. 2 シェルプログラムによる別コマンドの実行 180 6. 6. 3 コマンド引数の強制指定 182 6. 6. 4 隠れた OS Command 呼び出し 184 6. 6. 5 OS Command インジェクションの対策 187 6. 6. 6 OS Command インジェクションのためのエスケープ処理 189 6. 6. 7 OS Command インジェクションのためのエスケープ処理 (Linux 上の bash と tcsh) 192 6. 6. 8 OS Command インジェクションのためのエスケープ処理 (MS- WindowsNT 系列の cmd.exe) 195 6. 6. 9 OS Command インジェクションの対策 (PHP の escapeshellarg() 関数と escapeshellcmd() 関数 ) 200 6. 7 Script インジェクション eval() 関数への攻撃 201 6. 8 SQL インジェクション 203 6. 8. 1 SQL インジェクションの概略 203 14 目次.indd 14 08.3.24 6:09:32 PM
6. 8. 2 SQL 文の文字列リテラルとして使う場合 204 6. 8. 3 SQL 文の文字列リテラルとして使う場合 ( 対策編 ) 208 6. 8. 4 SQL エスケープ処理のための関数 210 6. 8. 5 SQL エスケープ処理の例外 mysql と PostgreSQL 212 6. 8. 6 SQL 文の数値として使う場合 213 6. 8. 7 SQL 文の数値として使う場合 ( 対策編 ) 217 6. 8. 8 数値として適切かどうかを確認する関数 219 6. 8. 9 SQL エスケープとデータ型チェックを自動で行う方法 ( 準備済み SQL 文 パラメータクエリ ) 220 6. 8. 10 SQL 文中のテーブル名や カラム名に入力データを配置させる場合 224 6. 8. 11 データベースに対しての負荷攻撃 226 6. 8. 12 データベース サーバでのアクセス権限もセキュリティ上重要 227 6. 8. 13 エラー画面を Web ブラウザに出さないこともセキュリティ上重要 229 6. 8. 14 Blind SQL インジェクションという驚異的攻撃手法 231 6. 8. 15 CSV 形式のデータに対しての攻撃手法 240 6. 8. 16 CakePHP フレームワーク特有の比較演算子インジェクション 242 6. 8. 17 Jet データベースへの OS Command インジェクション ( 過去の話題 ) 244 6. 9 LDAP インジェクション 245 6. 10 XPATH/XQuery インジェクション 255 6. 10. 1 XPATH/XQuery インジェクション 255 6. 11 Null インジェクション 257 6. 11. 1 Null インジェクションとは 257 6. 11. 2 Null インジェクションの対策 260 6. 11. 3 Null インジェクションの環境ごとの差異 261 6. 11. 4 Null インジェクション対策 ( ライブラリによる対策 ) 262 6. 12 CRLF インジェクション 263 6. 12. 1 CRLF インジェクションとは 263 6. 12. 2 CRLF インジェクション (HTTP ヘッダへのインジェクション ) 264 6. 12. 3 CRLF インジェクション ( 電子メールに対してのインジェクション ) 267 6. 12. 4 CRLF インジェクションのまとめ ( その他のプロトコルへの応用 ) 271 15 目次.indd 15 08.3.24 6:09:32 PM
7 ファイル パスと URL 272 7. 1 ファイルを安全に扱うために 272 7. 2 絶対パス指定の問題 273 7. 2. 1 絶対パス指定の問題 273 7. 2. 2 ネットワーク上のファイルを扱う 275 7. 3 ディレクトリ トラバーサル 277 7. 3. 1 ディレクトリ トラバーサルとは 277 7. 3. 2 ディレクトリ トラバーサルの対策 ( 基本 ) 279 7. 3. 3.. の監視は文字列の監視 / または の監視は文字の監視 282 7. 3. 4 手動でファイル パスの正規化を行う 284 7. 3. 5 関数を使ってファイル パスの正規化を行う 286 7. 3. 6 ディレクトリ トラバーサルの対策 ( まとめ ) 287 7. 4 NTFS とセキュアなファイル パスの取り扱い 288 7. 5 拡張子による制限 296 7. 6 ファイル名として許可されている文字や ファイル名の長さ 297 7. 7 ファイル アップロードとファイル名 300 7. 8 perl の open() 関数の場合 301 7. 9 IIS+ASP の 親のパスの有効化 オプション 305 7. 10 URL パスへ応用 310 7.10.1 ファイル パスの考えを URL パスにも応用する 310 7.10.2 蛇足 :URL と URI 310 7.10.3 URL の先頭はハードコーディングすること 311 7.10.4 URL の先頭は スキーム名 ホスト名までハードコーディングすること 311 7.10.5 Web 仮想ルートパスの / の重複( 相対パス指定時 ) 313 7.10.6 URL へ汚染データを埋め込むときは URL エンコードを行うこと 314 8 その他のセキュア プログラミング TIPS 315 8. 1 Web アプリケーションの各種ファイルの配置方法と最小権限の原則 315 8. 1. 1 Web アプリケーションの各種ファイルの配置方法 315 8. 1. 2 アクセス権はファイルにではなく ディレクトリに設定する 316 8. 2 乱数とセキュリティ 317 16 目次.indd 16 08.3.24 6:09:32 PM
8. 2. 1 乱数 317 8. 2. 2 rand () 関数を使う上での注意点 318 8. 2. 3 rand () 関数よりも推測困難な乱数関数を使用する 320 8. 2. 4 有効ビット数という考え方 323 8. 2. 5 推測困難な値の文字列長は長ければ長いほど安全性は高い 325 8. 3 暗号 ハッシュ 328 8. 3. 1 ハッシュ関数 暗号関数を使う 328 8. 3. 2 ハッシュ関数 暗号関数を使う上での注意点 332 8. 3. 3 RainbowCrack 334 8. 4 ユーザ アカウントのパスワード最大長 335 8. 5 DPAPI(Data Protection API) 336 8. 6 クライアント認証 337 8. 6. 1 クライアント認証とは 337 8. 6. 2 クライアント認証を実装する上での注意点 339 8. 6. 3 クライアント認証と IIS+ASP の Request オブジェクト 341 8. 6. 4 クライアント認証と IIS+ASP の Request オブジェクトから読み取れ る言語全般にわたる教訓 344 8. 7 Cookie の各種プロパティ 345 8. 7. 1 Cookie の secure オプション 345 8. 7. 2 Cookie の httponly オプション 350 8. 7. 3 その他の Cookie のオプション (Domain Path) 352 8. 8 圧縮ファイルとセキュリティ 352 8. 8. 1 伸張サイズ 353 8. 8. 2 展開先ディレクトリ 353 8. 8. 3 コンピュータウィルス チェック 353 8. 8. 4 伸張されたファイルのファイル名 354 8. 9 正規表現とセキュリティ 354 8. 10 クレジットカードのチェックサム 356 8. 11 文字コードによるサニタイジング回避テクニック 357 8. 11. 1 文字コードによるサニタイジング回避テクニックとは 357 8. 11. 2 Shift-JIS によるサニタイジング回避テクニック 357 8. 11. 3 UNICODE を使ったサニタイジング回避テクニック 359 17 目次.indd 17 08.3.24 6:09:33 PM
9 その他の Web アプリケーション開発時の注意事項 368 9. 1 そもそも Web アプリケーションである必要性はあるのか? 368 9. 2 画面デザイン上の問題 369 9. 2. 1 ポップアップする Web ページ ( 特にログイン画面 ) 369 9. 2. 2 ブラウザのアドレス欄 ステータスバーを表示したままにしておく 370 9. 2. 3 内部フレームに他の Web サイトのページを表示する 370 9. 3 ユーザ認証とエラー メッセージ そしてパスワード リマインダのメッセージ 371 9. 4 SSL のバージョン 372 9. 5 SSL の強制 373 9. 5. 1 概要 373 9. 5. 2 Apache の場合 373 9. 5. 3 IIS の場合 374 9. 6 SSL 証明書の信頼性 374 9. 7 その他の SSL 設定の問題 375 9. 7. 1 フレーム内部の SSL ページ 375 9. 7. 2 非 SSL ページから送信する Web ページ 376 9. 8 コンピュータウィルス チェック 376 9. 9 デフォルト コンテンツの削除 377 9. 9. 1 Apache の場合 377 9. 9. 2 IIS の場合 377 9. 9. 3 JavaServlet エンジンの場合 378 9. 10 ディレクトリ リスティングと既定コンテンツ 379 9. 10. 1 Apache の場合 379 9. 10. 2 IIS の場合 379 9. 11 OS ユーザの存在有無の脆弱性 381 9. 11. 1 Apache の場合 381 9. 12 TRACE メソッドの禁止 382 9. 12. 1 Apache の場合 382 9. 12. 2 IIS の場合 382 9. 13 プライベート IP アドレスの漏洩を防御する 383 9. 13. 1 IIS の場合 (content-location) 383 9. 13. 2 IIS の場合 (realm) 383 18 目次.indd 18 08.3.24 6:09:33 PM
9. 14 特定のファイルを読み出し禁止の設定にする 384 9. 14. 1 PHP の場合 384 9. 14. 2 Apache の場合 384 9. 14. 3 IIS の場合 385 9. 15 Web サーバ上でのアクセス権限について 386 9. 15. 1 スクリプトと静的コンテンツの分離 386 9. 15. 2 Apache の場合 387 9. 15. 3 IIS で設定できる二つのアクセス権グループ 387 9. 16 不要な拡張子マッピングは削除する 388 9. 16. 1 IIS の場合 388 9. 17 ファイルの存在の確認 389 9. 17. 1 IIS の場合 389 9. 18 拡張子マッピングで メソッドを制限する 390 9. 18. 1 IIS の場合 390 9. 19 エラー表示の抑制 392 9. 19. 1 PHP の場合 392 9. 19. 2 Tomcat の場合 392 9. 19. 3 Apache の場合 393 9. 19. 4 ASP.NET の場合 393 9. 19. 5 IIS の場合 393 9. 19. 6 まとめ 394 9. 20 SSI の設定 394 9. 20. 1 概要 394 9. 20. 2 Apache の場合 395 9. 21 親のパスを有効にする を無効にする 396 9. 21. 1 IIS の場合 396 9. 22 拡張されたファイル パスの抑制 399 9. 22. 1 PHP の場合 399 9. 23 PHP の設定ファイルについて 400 9. 24 PHP イースターエッグによるバージョン漏洩 400 9. 24. 1 PHP の場合 400 9. 25 ファイル アップロードの禁止 400 9. 25. 1 PHP の場合 400 19 目次.indd 19 08.3.24 6:09:33 PM
9. 26 バイナリファイルに保存されている XSS 攻撃コード 401 9. 26. 1 Apache の場合 401 9. 27 クエリ文字列セッション ID の禁止 401 9. 27. 1 PHP の場合 401 9. 27. 2 ASP.NET の場合 402 9. 27. 3 WebSphere の場合 402 9. 28 文字セットの強制 402 9. 28. 1 文字セット自動判断による XSS 攻撃 402 9. 28. 2 IIS の場合 403 9. 29 MS-WindowsNT 系でのログオン情報のキャッシュ 403 9. 30 MS-WindowsNT 系での LM Hash 403 9. 31 携帯向けコンテンツとフィルタリング 404 9. 32 リバース プロキシを使う場合 404 9. 33 メールサーバと Web アプリケーション 405 おわりに 406 索引 407 20 目次.indd 20 08.3.24 6:09:33 PM