---
title: 徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
tags:  #security  
author: [徳丸 浩](https://www.docswell.com/user/ockeghem)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/5DEY515MEM.jpg?width=480
description: PHPカンファレンス2012講演資料
published: September 15, 12
canonical: https://www.docswell.com/s/ockeghem/KYV1VK-phpconf2012
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/5DEY515MEM.jpg)

徳丸本に学ぶ
安全なPHPアプリ開発の鉄則2012
2012年9月15日
徳丸 浩


# Page. 2

![Page Image](https://bcdn.docswell.com/page/2VJNN2N3J8.jpg)

本日お話しする内容
• 鉄則1: PHP自体の脆弱性対処をしよう
• 鉄則2: Ajaxの脆弱性対処をしよう
• 鉄則3: 競合条件の脆弱性対処をしよう
• 鉄則4: htmlspecialcharsの使い方2012
• 鉄則5: escapashellcmdは使わないこと
• 鉄則6: SQLインジェクションの対処
• 鉄則7: クロスサイト･スクリプティングの対処
• 鉄則8: クロスサイト・リクエスト・フォージェリの対処
• 鉄則9: パスワードの保存はソルトつきハッシュ、できればスト
レッチングも
• 鉄則10: 他にもたくさんある脆弱性の対処
Copyright © 2012 HASH Consulting Corp.
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/GYE9R1RP73.jpg)

徳丸浩の自己紹介
• 経歴
– 1985年 京セラ株式会社入社
– 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍
– 2008年 KCCS退職、HASHコンサルティング株式会社設立
• 経験したこと
– 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当
– その後、企業向けパッケージソフトの企画・開発・事業化を担当
– 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当
Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始
– 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち上げ
• その他
– 1990年にPascalコンパイラをCabezonを開発、オープンソースで公開
「大学時代のPascal演習がCabezonでした」という方にお目にかかることも
• 現在
– HASHコンサルティング株式会社 代表
– 京セラコミュニケーションシステム株式会社 技術顧問
– 独立行政法人情報処理推進機構 非常勤研究員
Copyright © 2012 HASH Consulting Corp.
http://www.hash-c.co.jp/
http://www.kccs.co.jp/security/
http://www.ipa.go.jp/security/
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/5GE8W4WX7D.jpg)

鉄則1: PHP自体の脆弱性対処をしよう
Copyright © 2012 HASH Consulting Corp.
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/MLELN6NNJR.jpg)

PHPの脆弱性ってどれくらい危険なの?
Copyright © 2012 HASH Consulting Corp.
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/54JMX5XQ7W.jpg)

JVN iPediaで検索してみよう
http://jvndb.jvn.jp/search/index.php?mode=_vulnerability_search_IA_VulnSearch&amp;lang=ja
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/ZPJRN3NK79.jpg)

2011年5月以降のPHP高危険度脆弱性
JVN iPediaより引用
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/NPEXN4N5JX.jpg)

#1 JVNDB-2011-002207(CVE-2011-1938)
PHP の socket_connect 関数におけるスタックベースのバッファオーバーフローの脆弱性
概要
PHP の ext/sockets/sockets.c 内にある socket_connect 関数には、スタックベースのバッファ
オーバーフローの脆弱性が存在します。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.3.3 から 5.3.6
通常あり得ない想定
想定される影響
攻撃者により、UNIX ソケットの過度に長いパス名を介して、任意のコードを実行される可能性
があります。
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/63EKNZNRED.jpg)

#2 JVNDB-2011-002218(CVE-2011-3268)
PHP の crypt 関数におけるバッファオーバーフローの脆弱性
概要
PHP の crypt 関数には、バッファオーバーフローの脆弱性が存在します。
本脆弱性は、CVE-2011-2483 とは異なる脆弱性です。
CVSS による深刻度 (CVSS とは?)
基本値: 10.0 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 全面的
完全性への影響(I): 全面的
可用性への影響(A): 全面的
影響を受けるシステム
PHP 5.3.7 未満
通常あり得ない想定
想定される影響
攻撃者により、過度に長い salt 引数を介して、詳細不明な影響を受ける可能性があります。
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4L73VDVGE5.jpg)

#3 JVNDB-2011-002770(CVE-2011-3379)
PHP の is_a 関数における任意のコードを実行される脆弱性
概要
PHP の is_a 関数は、__autoload 関数の呼び出しを誘発するため、任意のコードを実行される
脆弱性が存在します。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.3.7
PHP 5.3.8
????
想定される影響
第三者により、巧妙に細工された URL、および特定の PEAR パッケージおよびカスタムオート
ローダの安全でない動作を利用されることで、任意のコードを実行される可能性があります。
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/V87D8P8N7G.jpg)

CVE-2011-3379入門
• 以下のソースの結果わかりますか? (PHP5.3.7～5.3.8)
function __autoload($class_name) {
echo &quot;autoload $class_name¥n&quot;;
}
class Class1 { }
$a = new Class1();
var_dump(is_a($a, &quot;Class1&quot;));
var_dump(is_a(&quot;test&quot;, &quot;Class1&quot;));
• 結果は以下の通り
bool(true)
autoload test
bool(false)
Copyright © 2012 HASH Consulting Corp.
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/4VJP8N8NJ8.jpg)

CVE-2011-3379のPoC
• 以下は脆弱なソース
// /var/data にユーザアップロードファイルが格納される想定
&lt;?php
require_once &#039;File.php&#039;;
function __autoload($class_name) {
include $class_name . &#039;.php&#039;;
}
$uploaded_filename = &#039;/var/data/test.dat&#039;;
$uploaded_file = File::readAll($uploaded_filename);
if (PEAR::isError($uploaded_file)){
echo &quot;error : $uploaded_file¥n&quot;;
}else{
echo &quot;success : $uploaded_file¥n&quot;;
}
• /var/data/test.dat の内容 /var/data/test2
• /var/data/test2.php がインクルードされる
Copyright © 2012 HASH Consulting Corp.
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/L2EVNKNY7Q.jpg)

CVE-2011-3379の影響を受ける条件(AND条件)
• __autoload関数によりクラスの自動ロード機能が定義されて
いる
• 直接・間接に、is_a関数に「攻撃者の入力した文字列」を渡
すことができる（PEARのFileクラスなど）
• 以下のいずれかにより任意スクリプトを指定できること
– アップロード機能などにより、サーバー上にPHPファイルを書き込み、
そのファイル名が推測できる
– allow_url_includeが有効になっている
• 影響を受ける環境はまれと推測される
Copyright © 2012 HASH Consulting Corp.
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/Z57GKQKWJL.jpg)

#4 JVNDB-2012-001323(CVE-2012-0830)
PHP の php_variables.c 内の php_register_variable_ex 関数における任意のコードを実行され
る脆弱性
概要
PHP の php_variables.c 内の php_register_variable_ex 関数には、任意のコードを実行され
る脆弱性が存在します。
本脆弱性は CVE-2011-4885 に対する修正が不十分だったことによる脆弱性です。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.3.9
想定される影響
第三者により、大量の変数を含むリクエストを介して、任意のコードを実行される可能性がありま
す。
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/V4EQNKNQEP.jpg)

#番外 JVNDB-2011-003565(CVE-2011-4885)
PHP におけるサービス運用妨害 (CPU 資源の消費) の脆弱性(hashdos)
概要
PHP は、ハッシュ衝突を想定した制限を行わずにフォームパラメータのハッシュ値を算出するた
め、サービス運用妨害 (CPU 資源の消費) 状態となる脆弱性が存在します。
CVSS による深刻度 (CVSS とは?)
基本値: 5.0 (警告) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): なし
完全性への影響(I): なし
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.3.9 未満
想定される影響
第三者により、巧妙に細工されたパラメータを大量に送信されることで、サービス運用妨害
(CPU 資源の消費) 状態にされる可能性があります。
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/DKJ4GPGYE1.jpg)

http://blog.tokumaru.org/2011/12/webdoshashdos.html
Copyright © 2012 HASH Consulting Corp.
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/PLE1D9DN7G.jpg)

#5 JVNDB-2011-001388(CVE-2012-0831)
PHP における SQL インジェクション攻撃を行われる脆弱性
概要
PHP は、環境変数のインポート中の magic_quotes_gpc ディレクティブへの一時的変更を適切
に処理しないため、容易に SQL インジェクション攻撃を行われる脆弱性が存在します。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.3.10 未満
アプリケーション側
でSQLインジェク
ション対策をしてい
れば問題ない
想定される影響
第三者により、main/php_variables.c、sapi/cgi/cgi_main.c、および
sapi/fpm/fpm/fpm_main.c に関連する巧妙に細工された要求を介して、容易に SQL インジェ
クション攻撃を行われる可能性があります。
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/8GEWYQ8MJ2.jpg)

勝手に訂正: 「PHP における SQL インジェクション攻
撃を行われる脆弱性 (JVNDB-2012-001388)」
http://co3k.org/blog/25 より引用
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/W47ZXW8MJ3.jpg)

#6 JVNDB-2012-002235(CVE-2012-1823)
PHP-CGI の query string の処理に脆弱性
概要
PHP には、CGI として使用される設定において query string をコマンドラインオプションとして認識してしま
う脆弱性が存在します。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP version 5.4.2 より前のバージョン
PHP version 5.3.12 より前のバージョン
PHP の開発者によると、本脆弱性の修正を含む更なるリリースを予定しているとのことです。
そのため、影響を受けるシステムに関する情報が今後変更される可能性があります。
想定される影響
遠隔の第三者によって、php スクリプトの内容を取得されたり、サービス運用妨害 (DoS) 攻撃を受けたり、
ウェブサーバの権限で任意のコードを実行されたりする可能性があります。
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/KYJ64GP5EV.jpg)

#7 JVNDB-2012-002392(CVE-2012-2311)
PHP の sapi/cgi/cgi_main.c における任意のコードを実行される脆弱性
概要
PHP の sapi/cgi/cgi_main.c は、CGI スクリプトとして設定される際、%3D 文字列を含み =
(等号) 文字を含まないクエリ文字列を適切に処理しないため、任意のコードを実行される脆弱
性が存在します。
本脆弱性は、CVE-2012-1823 に対する修正が不十分だったことによる脆弱性です。
CVSS による深刻度 (CVSS とは?)
基本値: 7.5 (危険) [NVD値]
攻撃元区分: ネットワーク
攻撃条件の複雑さ: 低
攻撃前の認証要否: 不要
機密性への影響(C): 部分的
完全性への影響(I): 部分的
可用性への影響(A): 部分的
影響を受けるシステム
PHP 5.4.3 未満の 5.4.x
PHP 5.3.13 未満
想定される影響
第三者により、クエリ文字列内にコマンドラインオプションを配置することで、任意のコードを実行
される可能性があります。
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/5GJ5QVKGE4.jpg)

CVE-2012-2311のPoC
allow_url_include=On
auto_prepend_file=php://input
&lt;?php readfile(‘/etc/passwd’); ?&gt;
Copyright © 2012 HASH Consulting Corp.
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/4LE3VDZPJ5.jpg)

飽きてきたので、この辺で…
Copyright © 2012 HASH Consulting Corp.
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/V8ED8PR3EG.jpg)

とりあえずのまとめ
• PHPの高危険度脆弱性は多いが、影響を受ける局面が限ら
れるものが多い
• アプリケーションが、当該脆弱性の影響を受けるか、外部か
らは判別しにくい
• アプリケーションやフレームワークの脆弱性の原因となった
場合、外部からの攻撃が容易となる
• IPA、JPCERT/CC、セキュリティ専門家の情報をウォッチし、
「騒ぎ出したら」急いで対処の準備をすること
Copyright © 2012 HASH Consulting Corp.
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/4V7P8NWP78.jpg)

脆弱性対処のアプローチ
• 正当的な方法
– 脆弱性情報が出る毎に影響を評価し、対処方法を決める
– 影響が大きく、回避策がある場合は、まず回避策を適用する
– パッチ、PHP新バージョンのアプリケーションに対する影響をテスト
する
– 本番環境にパッチ適用、バージョンアップ
• Linuxディストリビューションのパッチに任せる
– 基本的に、ディストリビューションのパッチが出るのを待って適用す
る
– テスト環境でパッチの影響を調べる
（えいやっ! で当ててしまうのもあり）
– 高危険度で攻撃が容易、かつパッチが間に合わない脆弱性につい
ては、回避策を適用する
Copyright © 2012 HASH Consulting Corp.
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/L2JVNK8VEQ.jpg)

鉄則2: Ajaxの脆弱性対処をしよう
Copyright © 2012 HASH Consulting Corp.
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/Z5EGKQ517L.jpg)

とある入門書のサンプル
よくわかるJavaScriptの教科書、たにぐちまこと著、2012 P228より引用
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/V4JQNKZNJP.jpg)

この本です
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/DK74GP33J1.jpg)

動かしてみる
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/PLJ1D91ZEG.jpg)

結果
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/8GJWYQ8672.jpg)

JSON作成をPHPに
生成されるJSON
[{&quot;image&quot;:&quot;img¥/1.jpg&quot;,&quot;image_big&quot;:&quot;i
mg¥/1_big.jpg&quot;,&quot;caption&quot;:&quot;¥u30ad¥u30e
3¥u30d7¥u30b7¥u30e7¥u30f31&quot;}]
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/W4EZXW8R73.jpg)

結果
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/KY764GP1JV.jpg)

データにJavaScriptを入れてみる
生成されるJSON
[{&quot;image&quot;:&quot;img¥/1.jpg&quot;,&quot;image_big&quot;:&quot;i
mg¥/1_big.jpg&quot;,&quot;caption&quot;:&quot;¥u30ad¥u30e
3¥u30d7¥u30b7¥u30e7¥u30f31&lt;script&gt;ale
rt(1)&lt;¥/script&gt;&quot;}]
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/5G75QVKLJ4.jpg)

結果
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/V9J2P3W3JR.jpg)

脆弱性の原因と対策
• htmlメソッドによりHTMLテキストを設定しているにも関わら
ず、データをHTMLエスケープしていない
• ただし、元文献は固定テキストなので、必ずしも脆弱性とは
言えない
• HTMLエスケープするタイミングは、以下の候補がある
– ブラウザでレンダリングする箇所
– JSONを組み立てる段階で、あらかじめHTMLエスケープしておく
Copyright © 2012 HASH Consulting Corp.
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/5DEY51L8EM.jpg)

次の話題
evalインジェクション
Copyright © 2012 HASH Consulting Corp.
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/2VJNN249J8.jpg)

JSON解釈をevalでやってみる
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/GYE9R1Q373.jpg)

JSON作成も自前で
&lt;?php
$image = &#039;img/1.jpg&#039;;
$image_big = &#039;img/1_big.jpg&#039;;
$caption = &#039;キャプション2&#039;;
$a = &#039;[{&quot;image&quot;:&quot;&#039; . $image . &#039;&quot;,&quot;image_big&quot;:&quot;&#039; .
$image_big . &#039;&quot;,&quot;caption&quot;:&quot;&#039; . $caption . &#039;&quot;}]&#039;;
echo $a;
生成されるJSON
[{&quot;image&quot;:&quot;img/1.jpg&quot;,&quot;image_big&quot;:&quot;img/1_b
ig.jpg&quot;,&quot;caption&quot;:&quot;キャプション2 &quot;}]
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/5GE8W4GL7D.jpg)

結果
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/MLELN6GQJR.jpg)

データにJavaScriptを入れてみる
&lt;?php
$image = &#039;img/1.jpg&#039;;
$image_big = &#039;img/1_big.jpg&#039;;
$caption = &#039;キャプション2x&quot;+alert(&quot;1&quot;)+&quot;&#039;;
$a = &#039;[{&quot;image&quot;:&quot;&#039; . $image . &#039;&quot;,&quot;image_big&quot;:&quot;&#039; .
$image_big . &#039;&quot;,&quot;caption&quot;:&quot;&#039; . $caption . &#039;&quot;}]&#039;;
echo $a;
生成されるJSON
[{&quot;image&quot;:&quot;img/1.jpg&quot;,&quot;image_big&quot;:
&quot;img/1_big.jpg&quot;,&quot;caption&quot;:
&quot;キャプション2x&quot;+alert(&quot;1&quot;)+&quot;&quot;}]
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/54JMX5LK7W.jpg)

結果
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/ZPJRN3K679.jpg)

脆弱性の原因と対策
• JSON/JavaScriptとしての適切なエスケープを怠っているこ
とが根本原因
• 根本単位策：JSON生成を自前でしないで、信頼できるライブ
ラリを用いる
• 保険的対策（強く推奨）:evalでJSONを解釈しない。
Copyright © 2012 HASH Consulting Corp.
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/NPEXN4LDJX.jpg)

次の話題
json.phpを直接ブラウズしてみる
Copyright © 2012 HASH Consulting Corp.
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/63EKNZLDED.jpg)

データを少しいじりましょう
Copyright © 2012 HASH Consulting Corp.
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/4L73VD3PE5.jpg)

さまざまなブラウザでの結果
Copyright © 2012 HASH Consulting Corp.
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/V87D8P437G.jpg)

で、IE9は?
Copyright © 2012 HASH Consulting Corp.
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/4VJP8NMPJ8.jpg)

大丈夫なのか
Copyright © 2012 HASH Consulting Corp.
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/L2EVNK9V7Q.jpg)

でも、だめ
http://example.jp/json.php/a.html
Copyright © 2012 HASH Consulting Corp.
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/Z57GKQZ1JL.jpg)

Copyright © 2012 HASH Consulting Corp.
http://d.hatena.ne.jp/hasegawayosuke/20110106/p1 より引用
48


# Page. 49

![Page Image](https://bcdn.docswell.com/page/V4EQNKLNEP.jpg)

Copyright © 2012 HASH Consulting Corp.
http://d.hatena.ne.jp/hasegawayosuke/20110106/p1 より引用
49


# Page. 50

![Page Image](https://bcdn.docswell.com/page/DKJ4GPD3E1.jpg)

X-Content-Type-Options: nosniff を入れてみる
生成されるJSON
X-Content-Type-Options: nosniff
Content-Length: 125
Content-Type: application/json; charset=utf8
[{&quot;image&quot;:&quot;img¥/1.jpg&quot;,&quot;image_big&quot;:&quot;img¥/1_b
ig.jpg&quot;,&quot;caption&quot;:&quot;¥u30ad¥u30e3¥u30d7¥u30b7¥
u30e7¥u30f31&lt;body onload=alert(1)&gt;&quot;}]
Copyright © 2012 HASH Consulting Corp.
50


# Page. 51

![Page Image](https://bcdn.docswell.com/page/PLE1D9ZZ7G.jpg)

IE9だとOK(IE8以上)
Copyright © 2012 HASH Consulting Corp.
51


# Page. 52

![Page Image](https://bcdn.docswell.com/page/8GEWYQ96J2.jpg)

IE7だとだめ
Copyright © 2012 HASH Consulting Corp.
52


# Page. 53

![Page Image](https://bcdn.docswell.com/page/W47ZXW9RJ3.jpg)

53


# Page. 54

![Page Image](https://bcdn.docswell.com/page/KYJ64GK1EV.jpg)

対策
• 必須対策（全ブラウザ共通）
– レスポンスがブラウザによりtext/htmlと解釈されないようにする
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf8
• IE6,7対策
– IE7以前をサポートしない
– ブラウザからの直接リクエストを受け付けない
– 「&lt;」、「&gt;」などもエスケープする
Copyright © 2012 HASH Consulting Corp.
54


# Page. 55

![Page Image](https://bcdn.docswell.com/page/5GJ5QVPLE4.jpg)

Json_encodeのパラメータを追加
生成されるJSON
[{&quot;image&quot;:&quot;img¥/1.jpg&quot;,&quot;image_big&quot;:&quot;img¥/1_bi
g.jpg&quot;,&quot;caption&quot;:&quot;¥u30ad¥u30e3¥u30d7¥u30b7¥u3
0e7¥u30f31¥u003Cbody onload=alert(1)¥u003E&quot;}]
Copyright © 2012 HASH Consulting Corp.
55


# Page. 56

![Page Image](https://bcdn.docswell.com/page/V9E2P363ER.jpg)

今度は大丈夫
Copyright © 2012 HASH Consulting Corp.
56


# Page. 57

![Page Image](https://bcdn.docswell.com/page/5D7Y51987M.jpg)

次の話題はJSONハイジャック
Copyright © 2012 HASH Consulting Corp.
57


# Page. 58

![Page Image](https://bcdn.docswell.com/page/2VENN2L9E8.jpg)

Firefox3などで発現。現在の主要ブラ
ウザでは対策されている
Copyright © 2012 HASH Consulting Corp.
58


# Page. 59

![Page Image](https://bcdn.docswell.com/page/GY79R143J3.jpg)

JSONハイジャックとは
• JSONを罠サイトからscript要素で読み出す
• 利用者のブラウザからは、正規のCookieが送信されるので、
認証ずみの状態でJSONが取得できる
• なんらかの手法で、このJSONの中味を読むのがJSONハイ
ジャック
これは罠サイト
&lt;script&gt;
ここにJSONを読み出す仕掛けを置く
// script要素で読み出したJSON
[{&quot;name&quot;:&quot;Yamada&quot;, &quot;mail&quot;:&quot;yama@example.jp&quot;}]
&lt;/script&gt;
Copyright © 2012 HASH Consulting Corp.
59


# Page. 60

![Page Image](https://bcdn.docswell.com/page/5G78W4QLJD.jpg)

サンプルスクリプト（罠）
Copyright © 2012 HASH Consulting Corp.
60


# Page. 61

![Page Image](https://bcdn.docswell.com/page/ML7LN6XQER.jpg)

結果
Copyright © 2012 HASH Consulting Corp.
61


# Page. 62

![Page Image](https://bcdn.docswell.com/page/54EMX53KJW.jpg)

Firefox11.0だと問題なし
Copyright © 2012 HASH Consulting Corp.
62


# Page. 63

![Page Image](https://bcdn.docswell.com/page/ZPERN3Q6J9.jpg)

Androidの標準ブラウザでハイジャック成功
Xperia ARC(SO-01C)
Android 2.3.4 でキャプチャ
Galaxy Nexus
Android 4.0.3では取得できず
Copyright © 2012 HASH Consulting Corp.
63


# Page. 64

![Page Image](https://bcdn.docswell.com/page/NP7XN45DEX.jpg)

対策
• script要素からのリクエストにはレスポンスを返さないように
する
– XMLHttpRequestからのリクエストに特別なヘッダを入れておき、
JSON提供側でチェックするなど
Jqueryの以下のヘッダを使っても良いかも
X-Requested-With: XMLHttpRequest
– POSTにのみ応答（個人的には好みません）
• JSONデータを、JavaScriptとして実行できない形にする
– 1行目に for(;;) ; を置く（個人的には好みません）
– JSONデータをJavaScriptとして実行できない形にする（同上）
• JSONハイジャック可能なブラウザを使わない（利用者側でと
れる対策）
Copyright © 2012 HASH Consulting Corp.
64


# Page. 65

![Page Image](https://bcdn.docswell.com/page/637KNZ6D7D.jpg)

鉄則3: 競合条件の脆弱性対処をしよう
Copyright © 2012 HASH Consulting Corp.
65


# Page. 66

![Page Image](https://bcdn.docswell.com/page/4LJ3VD6P75.jpg)

ドリランド カード増殖祭りはこうしておこ
った…かも?
Copyright © 2012 HASH Consulting Corp.
66


# Page. 67

![Page Image](https://bcdn.docswell.com/page/V8JD8PV3JG.jpg)

https://help.gree.jp/app/answers/detail/a_id/3231 より引用
67


# Page. 68

![Page Image](https://bcdn.docswell.com/page/4VEP8NVPE8.jpg)

こんな感じだった?
必要なもの 携帯もしくはPCを二台 gleeアカウント二つ
二台の機器でそれぞれのgleeアカウントでログインしてドリランド起
動後お互いでトレードさせる
トレード(受け取りはしない)が終わったら片方の機器はログアウトし
て二つの機器のアカウントを同じにする
それぞれトレード品受け取り画面にして受け取るボタン同時押し
カード毎にID振って無いのかよ。。。。
馬鹿じゃねぇの？
&gt;&gt;277
ちゃんとふってあるけど、トレード時にトレードされる側とする側で
ちゃんとアイテムIDが変わる仕様だったw
http://jin115.com/archives/51849925.html より引用
68


# Page. 69

![Page Image](https://bcdn.docswell.com/page/L27VNKZVJQ.jpg)

こんな感じだった?
DBからトレード元のカードのデータを読み取る
新しいIDをつけてトレード先に保存する
トレード元のデータを削除する
http://bakera.jp/ebi/topic/4722 より引用
69


# Page. 70

![Page Image](https://bcdn.docswell.com/page/Z5JGKQ41EL.jpg)

作ってみた
// トレードするカードのidと新オーナーのidがパラメータ
$item_id = (int)$_GET[&#039;item_id&#039;];
$newowner = (int)$_GET[&#039;newowner&#039;];
// カード情報を取得
$stmt = $pdo-&gt;query(
&quot;SELECT * FROM cards WHERE item_id=$item_id&quot;);
$row = $stmt-&gt;fetch(PDO::FETCH_ASSOC);
$kind = $row[&#039;kind&#039;];
$owner_id = $row[&#039;owner_id&#039;];
// トレード後のカードを作成
$stmt = $pdo-&gt;exec(&quot;INSERT INTO cards VALUES (NULL, $kind,&quot;.
&quot;$newowner, $item_id, $owner_id, NOW())&quot;);
// 元のカードを削除
$stmt = $pdo-&gt;exec(
&quot;DELETE FROM cards WHERE item_id= $item_id &quot;);
※デモスクリプトはプレースホルダをちゃんと使っています!
Copyright © 2012 HASH Consulting Corp.
70


# Page. 71

![Page Image](https://bcdn.docswell.com/page/V47QNKGN7P.jpg)

DEMO
Copyright © 2012 HASH Consulting Corp.
71


# Page. 72

![Page Image](https://bcdn.docswell.com/page/DKE4GP5371.jpg)

中ではこうなった
Copyright © 2012 HASH Consulting Corp.
72


# Page. 73

![Page Image](https://bcdn.docswell.com/page/PL71D9WZJG.jpg)

対策
• トランザクションを使う
– PDOの場合は、begeinTransaction ～ commit / rollbackの間
• ロック（排他制御）
– SELECT … FOR UPDATE など
• 上記の両方が必須
– トランザクションを使うだけでは排他制御にならない場合が多い
厳密にはDB依存 および モードに依存
• 「クリティカルセクション」に注意
– このスクリプトの場合は、SELECT ～ DELETE FROMまではクリテ
ィカルセクションであり、同一カードIDについては並行動作してはい
けない
• ちゃんとRDBを基礎から勉強しよう
Copyright © 2012 HASH Consulting Corp.
73


# Page. 74

![Page Image](https://bcdn.docswell.com/page/8G7WYQ66E2.jpg)

トランザクションと行ロックで対策
try {
$pdo-&gt;beginTransaction();
$item_id = (int)$_GET[&#039;item_id&#039;];
$stmt = $pdo-&gt;query(
&quot;SELECT * FROM cards WHERE item_id=$item_id FOR UPDATE&quot;);
$row = $stmt-&gt;fetch(PDO::FETCH_ASSOC);
if (! $row) throw new DataNotFoundException();
$kind = $row[&#039;kind&#039;];
$owner_id = $row[&#039;owner_id&#039;];
$stmt = $pdo-&gt;exec(&quot;INSERT INTO cards VALUES (NULL, $kind,&quot;.
&quot;$newowner, $item_id, $owner_id, NOW())&quot;);
$stmt = $pdo-&gt;exec(
&quot;DELETE FROM cards WHERE item_id=$item_id&quot;);
$pdo-&gt;commit();
} catch (DataNotFoundException $e) {
$pdo-&gt;rollback();
} catch (Exception $e) {
// ……
※上記は概要でありデモスクリプトはプレースホルダをちゃんと使っています!
Copyright © 2012 HASH Consulting Corp.
74


# Page. 75

![Page Image](https://bcdn.docswell.com/page/W4JZXWYRE3.jpg)

中ではこうなる
Copyright © 2012 HASH Consulting Corp.
75


# Page. 76

![Page Image](https://bcdn.docswell.com/page/KYE64GD17V.jpg)

鉄則4:
htmlspecialcharsの使い方2012
Copyright © 2012 HASH Consulting Corp.
76


# Page. 77

![Page Image](https://bcdn.docswell.com/page/5GE5QV3L74.jpg)

htmlspecialcharsの使い方
• PHPのリファレンスから
string htmlspecialchars ( string $string
[, int $flags = ENT_COMPAT | ENT_HTML401
[, string $encoding = ‘UTF-8’
[, bool $double_encode = true ]]] )
• 属性値をダブルクォートで囲むことにすれば、第2引数はデフ
ォルト値（ ENT_COMPAT ）で問題ない
• PHP5.4以降、文字エンコーディングのデフォルト（第3引数）
はUTF-8になった。mbstring.internal_encodingがUTF-8の
場合は指定しなくてもよくなった
– PHP5.4限定というのも難しいので当面は第3引数明示した方がよ
い
Copyright © 2012 HASH Consulting Corp.
77


# Page. 78

![Page Image](https://bcdn.docswell.com/page/V972P3Z37R.jpg)

鉄則5:
escapashellcmdは使わないこと
Copyright © 2012 HASH Consulting Corp.
78


# Page. 79

![Page Image](https://bcdn.docswell.com/page/5DJY51R8JM.jpg)

escapeshellcmdは仕様がおかしい
• escapeshellcmdはコマンドライン全体をまるっと指定して得スープする
ことを意図している
• しかし、パラメータ中に空白があった場合、パラメータの区切りが区別
できない
• すなわち、escapeshellcmdは、本質的にパラメータインジェクションの
危険性がある
– 例:
$cmd = &#039;grep &#039; . $_POST[’key’] . &#039;/var/data/data.txt&#039;;
$escaped_command = escapeshellcmd($cmd);
system($escaped_command);
– keyに下記を与えると
: /etc/passwd
– 以下が実行される
grep : /etc/passwd /var/data/data.txt
• 対策：escapeshellargを使う
Copyright © 2012 HASH Consulting Corp.
79


# Page. 80

![Page Image](https://bcdn.docswell.com/page/2V7NN2D978.jpg)

鉄則6: SQLインジェクションの対処
Copyright © 2012 HASH Consulting Corp.
80


# Page. 81

![Page Image](https://bcdn.docswell.com/page/GYJ9R1G3E3.jpg)

SQLインジェクション
• SQLインジェクションとは、
WHERE句に or ’a’=’a’ を追加する攻撃…ではない
• 多くの場合、SQL文の後半を自由に改変できる
– WHERE句の改変
– UNION SELECTの追加
– …
• DB内の任意テーブルの情報を取得可能
– 大規模な情報漏洩につながる
• MS SQLやPostgreSQLの場合、第2、第3のSQL文を追加
できる（複文の実行）
– 複文が実行できる場合、データの改変、追加、削除が可能
Copyright © 2012 HASH Consulting Corp.
81


# Page. 82

![Page Image](https://bcdn.docswell.com/page/5GJ8W4VLED.jpg)

SQLインジェクション対策
• プレースホルダを用いてSQL文を呼び出す…の一択
– エスケープはややこしすぎる
• DB接続の際に文字エンコーディングを指定すること
• （できれば）静的プレースホルダを用いること
• 安全なSQLの呼び出し方を良く読むこと（無料です）
Copyright © 2012 HASH Consulting Corp.
82


# Page. 83

![Page Image](https://bcdn.docswell.com/page/MLJLN65Q7R.jpg)

鉄則7: クロスサイト･スクリプティングの
対処
Copyright © 2012 HASH Consulting Corp.
83


# Page. 84

![Page Image](https://bcdn.docswell.com/page/547MX5RKEW.jpg)

クロスサイトスクリプティング(XSS)とは
• XSSは、ブラウザ上でalertを表示する攻撃…ではない
• 攻撃者が、一般利用者のブラウザ上で、勝手なJavaScriptを
実行できる脆弱性 / 攻撃手法
• それって、ウイルス?
– XSS自体はウイルスではないが、XSS脆弱性を悪用してウイルス
の一種（ワーム）を作ることはできる
– 不正確だが「ウイルスのように凶悪なもの」という理解はあり
• 対策は、HTMLのエスケープ
– これが複雑
Copyright © 2012 HASH Consulting Corp.
84


# Page. 85

![Page Image](https://bcdn.docswell.com/page/ZP7RN3R6E9.jpg)

HTMLの構成要素
Copyright © 2012 HASH Consulting Corp.
85


# Page. 86

![Page Image](https://bcdn.docswell.com/page/NPJXN4RD7X.jpg)

HTMLエスケープの概要
場所
説明
エスケープの概要
要素内容（通常の タグと文字参照が解釈さ
「&lt;」と「&amp;」を文字参照に
テキスト）
れる「&lt;」で終端
属性値
属性値(URL)
文字参照が解釈される
引用符で終端
属性値を「”」で囲み、「”」と
「&amp;」を文字参照に
同上
URLの形式を検査してから
属性値としてのエスケープ
JavaScriptとしてエスケープ
イベントハンドラ内
同上
してから属性値としてのエス
の文字列リテラル
ケープ
JavaScriptとしてのエスケー
script要素内の文 タグも文字参照も解釈さ
プおよび「&lt;/」が出現しないよ
字列リテラル
れない。「&lt;/」により終端
う考慮
Copyright © 2012 HASH Consulting Corp.
86


# Page. 87

![Page Image](https://bcdn.docswell.com/page/63JKNZRDJD.jpg)

鉄則8: クロスサイト・リクエスト・フォージ
ェリの対処
Copyright © 2012 HASH Consulting Corp.
87


# Page. 88

![Page Image](https://bcdn.docswell.com/page/4LE3VD8PJ5.jpg)

クロスサイト・リクエスト・フォージェリの対処
• クロスサイト・リクエスト・フォージェリ(CSRF)とは
– Webアプリケーションの「機能」を勝手に実行させられる
– サーバー側の作用（更新、送金、投稿、削除…）に限られる
• 勝手に実行させられるのは、「サーバー側に元々ある機能」
– SQLインジェクションは任意のSQLが実行可能
– XSSは任意のJavaScriptが実行可能…という点で異なる
• でも、XSSとCSRFは、なんか、似ている
Copyright © 2012 HASH Consulting Corp.
88


# Page. 89

![Page Image](https://bcdn.docswell.com/page/V8ED8PM3EG.jpg)

反射型XSSとCSRFの比較
徳丸本P147より引用
Copyright © 2012 HASH Consulting Corp.
89


# Page. 90

![Page Image](https://bcdn.docswell.com/page/4V7P8NRP78.jpg)

クリックジャッキング攻撃
• 機能を勝手に実行させられるという点でCSRFと類似
• ターゲットの画面をiframe上で「透明に」表示する
• その下にダミーの画面を表示させる。ユーザにはダミーの画
面が透けて見える
• 利用者がダミーの画面上のボタンを押すと、実際には全面の
ターゲット画面のボタンが押される
本当の画面（前面、透明）
ダミーの画面（後面）
Copyright © 2012 HASH Consulting Corp.
90


# Page. 91

![Page Image](https://bcdn.docswell.com/page/L2JVNKRVEQ.jpg)

CSRF/クリックジャッキングの対策
• CSRF対策はトークンによる方法に統一しよう
– 「ワンタイムトークン」である必要はない
• クリックジャッキングされると困るページには、X-FRAME-OPTIONSヘッダを指定す
る（徳丸本P63）
– frame/iframeを禁止して良い場合
header(&#039;X-FRAME-OPTIONS&#039;, &#039;DENY&#039;);
– frame/iframeを禁止できないが単一ホストの場合
header(&#039;X-FRAME-OPTIONS&#039;, &#039;SAMEORIGIN&#039;);
• CSRF対策のトークン発行しているページが対象となる
入力画面
メールアドレス
foo@pexample.jp
実行画面
メールアドレスアドレスを
変更しました
変更
header(&#039;X-FRAME-OPTIONS&#039;, &#039;DENY&#039;);
…
&lt;input type=&quot;hidden&quot; name=&quot;token&quot;
value=&quot;a89daf89af0…&quot;&gt;
セッション等に保存したtokeとhiddenの
token値を比較)
Copyright © 2012 HASH Consulting Corp.
91


# Page. 92

![Page Image](https://bcdn.docswell.com/page/Z5EGKQM17L.jpg)

鉄則9: パスワードの保存はソルトつき
ハッシュ、できればストレッチングも
Copyright © 2012 HASH Consulting Corp.
92


# Page. 93

![Page Image](https://bcdn.docswell.com/page/V4JQNKRNJP.jpg)

どうして暗号化ではなくてハッシュなの?
• 暗号化の場合、鍵の管理が難しい
• アプリケーションは鍵を使わなければならないが、攻撃者には鍵を見せ
たくない
• PSNの事件では、権限昇格されたことになっているので、暗号鍵も盗ま
れていると想定せざるを得ない
• ハッシュだと鍵を使わないので、鍵管理のわずらわしさがない
• パスワードをサイト管理者にも知られたくないというニーズも
– 暗号化されたパスワードだと、サイト管理者やヘルプデスク担当者がパスワードを
知り得るのが嫌だ
– ヘルプデスクに見せないようにするには、サポート用画面の機能次第で可
– 管理者の悪事は総合的な対策が必要で、パスワードの問題だけではない
• PCI-DSS2.0 8.4項には「8.4 強力な暗号化を使用して、すべてのシス
テムコンポーネントでの伝送および保存中のすべてのパスワードを読
み取り不能にする」とあり、ハッシュを求めてはいない
Copyright © 2012 HASH Consulting Corp.
93


# Page. 94

![Page Image](https://bcdn.docswell.com/page/DK74GP83J1.jpg)

ハッシュで保存されたパスワードは本当に安全なの?
• 一般的に、（暗号論的）ハッシュ値から平文を「復元する」ことはできな
い
– 「password」のMD5ハッシュ: 5f4dcc3b5aa765d61d8327deb882cf99
• しかし、パスワードの場合は特別な事情がある
• 例：4桁の暗証番号をハッシュ値で保存している場合
– 全ての可能性は1万通りしかないのだから、総当たりで確認すれば、平文の暗証
番号はすぐに判明する
• 原理は8桁パスワードでも同じ
• ハッシュ保存の場合、アルゴリズムは攻撃者が知っている前提で安全
な設計とする
– 平文パスワード以外は、すべて「ばれている」想定を置く
• 攻撃者にとって未知であることが保証された情報があれば、それを鍵と
して暗号化すればよい。現実にはそのような保証がないから暗号化を
用いない
Copyright © 2012 HASH Consulting Corp.
94


# Page. 95

![Page Image](https://bcdn.docswell.com/page/PLJ1D92ZEG.jpg)

Saltってなに?
• ソルト（Salt）とは、ハッシュの元データ（パスワード）に追加する文字列
• 見かけのパスワードの長さを長くする
– 公開されたレインボーテーブルは10文字までのパスワードに対応しているので、
パスワードとソルトを合わせて20文字以上にしておけば、当面は大丈夫
• ユーザ毎にソルトを変えることで、パスワードが同じでも、異なるハッシ
ュ値が得られる
• ソルトの要件
– ある程度の長さを確保すること
– ユーザ毎に異なるものにすること
• ソルトには乱数を用いることが多いが、乱数が必須というわけではない
（暗号論的に安全な乱数である必要はもちろんない）
• ソルトは秘密情報ではない。ソルトは、通常ハッシュ値と一緒に保存す
る
Copyright © 2012 HASH Consulting Corp.
95


# Page. 96

![Page Image](https://bcdn.docswell.com/page/8GJWYQR672.jpg)

Stretchingってなに?
• ストレッチング（Stretching）とは、ハッシュの計算を繰り返すこと
• ハッシュの計算を遅くすることにより、辞書攻撃や総当たり攻撃に対抗
する
• 1万回ストレッチすると、「 GPU で 7 時間である」が7万時間になる計算
– 7万時間 = 2916日 = 約8年
• 「悪い」パスワードまで救えるわけではない
– 「password」というパスワードをつけていたら、100万回ストレッチしてもすぐに解
読されてしまう
• 十分長いパスワードをつけてもらえば、ストレッチングは必要ない
– 1文字パスワードを長くすることは、約100回のストレッチングに相当する。パスワ
ードを2文字長くしてもらえば…
– でも、中々難しいのでストレッチングの値打ちがある
• ストレッチングはメリットとデメリットがあるので、導入の有無と回数をよ
く検討すること
Copyright © 2012 HASH Consulting Corp.
96


# Page. 97

![Page Image](https://bcdn.docswell.com/page/W4EZXWRR73.jpg)

鉄則10: 他にもたくさんある
脆弱性の対処
Copyright © 2012 HASH Consulting Corp.
97


# Page. 98

![Page Image](https://bcdn.docswell.com/page/KY764GR1JV.jpg)

徳丸本に載っている主な脆弱性
4.3.1 クロスサイト・スクリプティング
4.4.1 SQLインジェクション
4.5.1 クロスサイト・リクエストフォージェリ（CSRF）
4.6.2 推測可能なセッションID
4.6.3 URL埋め込みのセッションID
4.6.4 セッションIDの固定化
4.7.1 オープンリダイレクタ脆弱性
4.7.2 HTTPヘッダ・インジェクション
短時間ではとても
4.8.2 クッキーのセキュア属性不備
説明できません
4.9.2 メールヘッダ・インジェクション脆弱性
4.10.1 ディレクトリ・トラバーサル脆弱性
4.10.2 意図しないファイル公開
4.11.1 OSコマンド・インジェクション
4.12.2 アップロードファイルによるサーバー側スクリプト実行
4.12.3 ファイルダウンロードによるクロスサイト・スクリプティング
4.13.1 ファイルインクルード攻撃
4.14.1 evalインジェクション
4.15.1 競合状態の脆弱性
Copyright © 2012 HASH Consulting Corp.
98


# Page. 99

![Page Image](https://bcdn.docswell.com/page/5G75QV8LJ4.jpg)

結論
徳丸本を買ってよく読め
ご清聴ありがとうございました
Copyright © 2012 HASH Consulting Corp.
99


