20090218 第5回「PhpによるWebアプリケーションのセキュリティ入門」

4,014 views

Published on

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,014
On SlideShare
0
From Embeds
0
Number of Embeds
1,552
Actions
Shares
0
Downloads
21
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

20090218 第5回「PhpによるWebアプリケーションのセキュリティ入門」

  1. 1. 「 PHP による web アプリケーションの セキュリティ入門」 第5回社内勉強会
  2. 2. 攻撃を防ぐには <ul><li>攻撃の種類を知る </li></ul><ul><li>防御の方法を知る </li></ul><ul><ul><ul><ul><ul><li>なにより </li></ul></ul></ul></ul></ul><ul><li>攻撃されている、 ということを知る </li></ul>
  3. 3. 本日のお題 <ul><li>PHP による web アプリケーションの セキュリティ入門 </li></ul>
  4. 4. 本日の目標 <ul><li>業務でおなじみ PHP を例に </li></ul><ul><li>PHP に限ったことじゃない </li></ul><ul><li>基礎知識と危機感を 持って帰ってください </li></ul>
  5. 5. 本日ご紹介しますのは <ul><li>XSS </li></ul><ul><li>CSRF </li></ul><ul><li>SQL インジェクション </li></ul>
  6. 6. クロスサイトスクリプティング <ul><li>略称: XSS </li></ul><ul><li>入力データを無防備に HTML 出力  ↓ </li></ul><ul><li>ブラウザがタグとして解釈  ↓ </li></ul><ul><li>当然 <script> タグも有効  ↓ </li></ul><ul><li>閲覧したクライアント上で 任意の JavaScript コードを実行させることができる </li></ul>
  7. 7. やってみよう <ul><li>デモ </li></ul>
  8. 8. クロスサイトスクリプティング <ul><li>JavaScript を実行されるとこんなに危険 </li></ul><ul><li>クッキーの値を設定・取得できる </li></ul><ul><ul><li>セッションハイジャック </li></ul></ul><ul><li>意図しないページ遷移を起こさせる </li></ul><ul><ul><li>クロスサイト・リクエスト・フォージェリ ( 後述 ) </li></ul></ul><ul><li>ページ全体を置き換える </li></ul><ul><ul><li>フィッシング </li></ul></ul><ul><li>フォームのアクションを書き換える </li></ul><ul><ul><li>フォーム情報の不正取得 </li></ul></ul>
  9. 9. 対策 <ul><li>表示するときは文字列をエスケープする </li></ul><ul><li>htmlspecialchars($value, ENT_QUOTES) ; </li></ul><ul><li>http://jp.php.net/htmlspecialchars </li></ul>'&' ( アンパサンド ) は '&amp;' になります。 ENT_NOQUOTES が設定されていない場合、 '&quot;' ( ダブルクォート ) は '&quot;' になります。 ENT_QUOTES が設定されている場合のみ、 ''' ( シングルクオート ) は ''' になります。 '<' ( 小なり ) は '&lt;' になります。 '>' ( 大なり ) は '&gt;' になります。
  10. 10. 不十分な場合もある・1 <ul><li>タグの属性に出力する場合 </li></ul><a href=&quot;{$url}&quot;>LINK</a> $url = htmlspecialchars( &quot;javascript:alert(document.cookie)&quot;, ENT_QUOTES) ; <ul><li>安全な URL であるかチェックする必要がある </li></ul><ul><li>IE のバグ: java script:alert() </li></ul>
  11. 11. 不十分な場合もある・2 <ul><li>そもそも設計を見直すべき場合 </li></ul><script> {$hoge} </script> <style> {$piyo} </style> <ul><li>それは本当に必要か? </li></ul>
  12. 12. 入力に HTML タグを許可したい場合 <ul><li>結構大変 </li></ul><ul><li>例:はてなダイアリーの場合 </li></ul><ul><ul><ul><li>ホワイトリストで制限する </li></ul></ul></ul><ul><ul><ul><li>独自タグを実装する </li></ul></ul></ul><ul><ul><ul><li>あきらめる </li></ul></ul></ul>
  13. 13. まとめ <ul><li>クライアントから送られてくる値は信用しない </li></ul><ul><ul><li>$_GET, $_POST </li></ul></ul><ul><ul><li>$_REQUEST は使わないようにしよう </li></ul></ul><ul><li>エスケープは表示する直前に行う </li></ul><ul><ul><li>元データを加工してしまうと転用しづらい </li></ul></ul><ul><li>私たちはケータイだから関係ないや </li></ul><ul><ul><li>… と思わずしっかり対策する </li></ul></ul>
  14. 14. クロスサイト・リクエスト・フォージェリ <ul><li>略称:CSRF / XSRF </li></ul><ul><ul><ul><li>「しーさーふ」ってダサいよね </li></ul></ul></ul><ul><li>攻撃者が攻撃用のページを用意  ↓ </li></ul><ul><li>利用者がアクセスすること  ↓ </li></ul><ul><li>攻撃リクエストが送信される </li></ul>
  15. 15. やってみよう <ul><li>デモ </li></ul>
  16. 16. クロスサイト・リクエスト・フォージェリ <ul><li>恐ろしいところ: 正規のリクエストと見分けがつかない </li></ul><ul><li>対策が大変 </li></ul><ul><ul><li>パスワードを再入力させる </li></ul></ul><ul><ul><li>CAPTCHA を使う </li></ul></ul><ul><ul><li>トークンを使う </li></ul></ul>
  17. 17. トークン?CAPTCHA? <ul><li>トークンって? </li></ul><ul><ul><li>ユーザごとに固有の値 </li></ul></ul><ul><ul><li>登録時に一度だけ生成する使い捨ての値 </li></ul></ul><ul><ul><ul><li> ワンタイムトークン </li></ul></ul></ul><ul><li>CAPTCHA </li></ul><ul><ul><li>こんなの </li></ul></ul>
  18. 18. トークンによる対策の概要 <ul><li>フォームでトークン生成  ↓ </li></ul><ul><li>hiddenフィールドから一緒に送信 </li></ul><ul><li>サーバ側でセッションに格納  ↓ </li></ul><ul><li>リクエストとセッションを突き合わせる  ↓ </li></ul><ul><li>合致したら正当なリクエストとして扱う </li></ul>
  19. 19. 私たちは携帯向けサイトを作っている <ul><li>cookieが使えない </li></ul><ul><ul><li>セッションIDをURLで引き回すのも前時代的 </li></ul></ul><ul><li>webサーバが複数ある </li></ul><ul><ul><li>PHP標準のセッション機能が使えない </li></ul></ul><ul><li>油断しがち </li></ul><ul><ul><li>「ソースが見えない」 「パラメータは改竄できない」は 幻想 </li></ul></ul>
  20. 20. 対策いろいろ <ul><li>端末識別 ID による認証 </li></ul><ul><ul><li>ケータイサイトでは基本 </li></ul></ul><ul><ul><ul><li>賛否両論ありますが… </li></ul></ul></ul><ul><li>クリティカルな箇所はトークン </li></ul><ul><ul><li>チートページを作って自分自身のアカウントを攻撃  ↓ </li></ul></ul><ul><ul><li>自分のパラメータを書きかえられちゃうとマズー </li></ul></ul><ul><ul><li>DB 、 memcached などを使っていろいろ実装する必要がある </li></ul></ul><ul><li>入力値のチェック </li></ul><ul><ul><li>クライアントから送られてくる値は信用しない </li></ul></ul><ul><ul><li>$_GET, $_POST </li></ul></ul><ul><ul><li>$_REQUEST は使わないようにしよう </li></ul></ul><ul><ul><ul><li>大事なことなので二回言いました </li></ul></ul></ul>
  21. 21. まとめ <ul><li>いろいろ大変 </li></ul><ul><li>手を抜くと被害が大きい </li></ul><ul><li>大変だが油断しないこと </li></ul><ul><ul><li>人には言えない痛い目に遭ってます </li></ul></ul>
  22. 22. SQLインジェクション <ul><li>アプリケーションが想定しない SQL文を実行させること </li></ul><ul><li>デモスクリプトで削除に使ってるクエリ </li></ul>$sql = &quot;DELETE FROM bbs&quot; . &quot; WHERE id = { $_POST['id'] }&quot; . &quot; AND pass = '{$_POST['pass']}' &quot; . &quot; LIMIT 1&quot; ; <ul><li>見るからに危険 </li></ul>
  23. 23. こんな攻撃ページを作った <form action=&quot;http://localhost/Part2/2-1.php&quot; method=&quot;POST&quot;> sql:<input type=&quot;text&quot; name=&quot;id“ value=&quot; 0 OR 1 # “ readonly=&quot;true&quot; /><br /> <input type=&quot;submit&quot; name=&quot;delete“ value=&quot;Do It!&quot; /> </form>
  24. 24. やってみよう <ul><li>デモ </li></ul>
  25. 25. SQLにパラメータを埋め込む <ul><li>展開すると MySQLは[#]から行末までと [/* ~ */]がコメント </li></ul><ul><li>ということは… </li></ul>DELETE FROM bbs WHERE id = 0 OR 1 # AND pass = '' LIMIT 1
  26. 26. 対策 <ul><li>プリペアドステートメントとバインド使え。 以上。 </li></ul><ul><li>PHP 5.2以上は PDOで… </li></ul>$sql = &quot;DELETE FROM bbs&quot; . &quot; WHERE id = :id&quot; . &quot; AND pass = :pass &quot; . &quot; LIMIT 1&quot; ; $pdo = new PDO($connection_param) ; $stmt = $pdo->prepare($sql) ; $stmt->bindParam(&quot;:id&quot;, $_POST['id'] , PDO::PARAM_INT) ; $stmt->bindParam(&quot;:pass&quot;, $_POST['pass'], PDO::PARAM_STR) ; $stmt->query() ;
  27. 27. 使えない場合は?(数値型) <ul><li>数値型は数値としての妥当性をチェックする </li></ul><ul><ul><li>intval() </li></ul></ul><ul><ul><li>is_int() </li></ul></ul><ul><ul><li>is_numeric() </li></ul></ul><ul><ul><li>preg_match(&quot;/^[0-9]+$/&quot;, $param) </li></ul></ul><ul><li>それぞれ挙動が違うので 適切なものを利用する </li></ul>
  28. 28. 使えない場合は?(文字列型・1) <ul><li>データベース接続モジュールが提供する エスケープ関数を利用する </li></ul><ul><ul><li>string mysql_escape_string( string $unescaped_string) </li></ul></ul><ul><ul><li>string pg_escape_string( [resource $connection], string $data) </li></ul></ul>
  29. 29. 使えない場合は?(文字列型・2) <ul><li>自力でエスケープ </li></ul><ul><li>PostgreSQL は 8.1.4 から 設定で「 ‘ 」を拒否できるようになった </li></ul><ul><ul><li>「 '' 」を使うのが望ましい 1 </li></ul></ul> ‘’ or ’ ‘ MySQL PostgreSQL ‘’ ‘ Oracle MS SQL DB2 エスケープ 元の文字 DB
  30. 30. 全体のまとめ <ul><li>一番よくある攻撃3種類を簡単に紹介 </li></ul><ul><li>攻撃されることを前提にした 設計・コーディングを </li></ul><ul><ul><li>リクエストパラメータは絶対に信用しない </li></ul></ul><ul><ul><li>攻撃者は執念深い </li></ul></ul><ul><ul><li>「ケータイだから」と油断は禁物 </li></ul></ul><ul><li>攻撃方法はこれだけじゃない </li></ul><ul><ul><li>常に情報を収集する努力を </li></ul></ul>
  31. 31. 必読 <ul><li>PHPサイバーテロの技法 ―攻撃と防御の実際 </li></ul><ul><ul><li>社内蔵書にあるので必読 </li></ul></ul><ul><ul><li>この本だけで十分とは 言い切れないのが恐ろしい </li></ul></ul>
  32. 32. リンク集 <ul><li>クロスサイトスクリプティング - Wikipedia </li></ul><ul><ul><ul><ul><li>http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0 </li></ul></ul></ul></ul><ul><li>クロスサイトリクエストフォージェリ - Wikipedia </li></ul><ul><ul><ul><ul><li>http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA </li></ul></ul></ul></ul><ul><li>SQL インジェクション - Wikipedia </li></ul><ul><ul><ul><ul><li>http://ja.wikipedia.org/wiki/SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3 </li></ul></ul></ul></ul><ul><li>開発者のための正しい CSRF 対策 </li></ul><ul><ul><ul><ul><li>http://www.jumperz.net/texts/csrf.htm </li></ul></ul></ul></ul><ul><li>はてなダイアリー XSS 対策 - はてなダイアリーのヘルプ </li></ul><ul><ul><ul><ul><li>http://hatenadiary.g.hatena.ne.jp/keyword/%e3%81%af%e3%81%a6%e3%81%aa%e3%83%80%e3%82%a4%e3%82%a2%e3%83%aa%e3%83%bcXSS%e5%af%be%e7%ad%96 </li></ul></ul></ul></ul><ul><li>徳丸浩の日記 – そろそろ SQL エスケープに関して一言いっとくか – SQL のエスケープ再考 </li></ul><ul><ul><ul><ul><li>http://www.tokumaru.org/d/20080601.html#p01 </li></ul></ul></ul></ul><ul><li>Amazon.co.jp : PHP サイバーテロの技法―攻撃と防御の実際 </li></ul><ul><ul><ul><ul><li>http://www.amazon.co.jp/gp/product/4883374718/ref=sib_rdr_dp </li></ul></ul></ul></ul>
  33. 33. おしまい <ul><li>ご清聴ありがとうございました </li></ul>

×