狠狠撸

狠狠撸Share a Scribd company logo
オープンソースカンファレンス2011 Hokkaido



   PHPで
 セキュリティを
 真面目に考える
               LOCAL PHP部   佐藤琢哉(nazo)
配布向け注意事項
? この資料はOSC2011Hokkaido用の45分資料を、
 配布用に再編集したものです。
? セキュリティという広いテーマを扱うのに45
 分という時間はすごく足りなく、最初から全
 てを網羅するつもりはありません。そのため、
 抜けている内容が多いと思いますが、[後で吊
 す]タグを付けたりするのはご遠慮下さい。
少   向




        ?
            PHP
                  セ




                      ?
な   け   基         ミ   セ   今
い   で   本   の     ナ   キ   回
か   す   的   ネ     ー   ュ   の
も   が   に   タ     と   リ   内
し   、   初   が     被   テ   容
れ   細       メ     る   ィ
    か   心             ネ
ま       者   イ     か
    い       ン         タ
せ       ~         と   で
ん   解       で     思
    説   中             他
。       級   す     っ
    は       。     た   の
        者         の
                  で
これだけ覚えて!
?常に最新のPHPを使う

?最新のライブラリなどを使う

?正しい情報、一次情報を確認する

?何も信用しない
自己紹介
?佐藤琢哉
?nazo
?LOCAL PHP部
?8月からニートフリーランス
?twitter : @nazo
笔贬笔はセキュリティに弱い?


            弱い
            弱くない
            知らない
            最強




      (nazo脳内調べ)
笔贬笔=セキュリティに弱い
       という印象




   ※この内容は現在は修正されています。
なんでそういうイメージなの?


? 利用者が多い

 ? =レベルが低い人も多い

? PHPに落とし穴が多い
うへへ、よく知らない
  から適当に
 作っちゃうZE☆



 警察の
ものです
 がー
知らないことは
 罪である
知らないことを
回避するために


 「調べられる知識」を
 付けることが重要
セキュリティの極意


  守破離
守 基礎を知る

破 基礎を実践できるようになる?
組み合わせて考えれるようになる

離 自分でセキュリティを考えられ
るようになる
…それを全て话すと终わらないので




    今回は笔贬笔の话
笔贬笔でセキュリティを真面目に考える
古いPHPを使うとこんなに危険!
?最近見つかった脆弱性が修正されていない

?脆弱性対策になる関数が入っていない

?最新の脆弱性の情報が流れてこない
古い笔贬笔+古いソフトウェアの组み
    合わせはもっと危険
?特定の脆弱性を狙い撃ちにできる

?BOT等でその脆弱性だけを無差別に狙う

?動作しているプログラムも知られている
ため、簡単に攻撃できる
PHP本体のバグ
?基本的にはそれほど多くない

?きわどい使い方をするとまれにひっかかる

?最新バージョンを使うことが大事

?PHP4は使ってはいけない
 ?可能な限りPHP5.3
PHP本体のバグ 最近の例
?文字列“2.2250738585072011e-308”をdouble
 にキャストするとハングアップする
  ?内部で無限ループになる

?32bitプロセスのみで再現
?$d = (double)"2.2250738585072011e-308";
?PHP5.3.5/PHP5.2.17で修正済
笔贬笔でセキュリティを真面目に考える
PHPの駄目な設定
? safe_mode=On
? register_globals=On
? magic_quotes_gpc=On
? allow_url_include=On
? allow_url_fopen=On
? error_reporting=E_ALL^E_NOTICE
safe_mode
? 共用サーバー向けの設定
? 名前からして、設定すると安全になりそうな風に見えるが…
? 「他の人のファイル参照を難しくする」程度で、「完全に他の人の
  ファイルを参照できなくする」ことはできない。
? 特に必要がない限りOFFにすべき
   ? 自分で設定できるのであれば基本的にOFF
? PHP5.3では非推奨(E_DEPRECATED)
   ? PHP6では廃止予定
? http://php.net/manual/ja/ini.sect.safe-mode.php
registar_globals
? $_GETや$_POSTに入る値をグローバル変数に自動展開
 する
? グローバル変数の初期値が変わってしまうことにより、
 バグになる可能性
? 外部からやりたい放題になる可能性がある
? 無条件でOFFにすべき
? PHP5.3では非推奨(E_DEPRECATED)
? 他のregister_xxx系も禁止
magic_quotes_gpc
? 怪しい記号を¥でエスケープしてくれる
? 必要がなくてもエスケープされてしまう
? 漏れるケースが存在する
? 無条件でOFFにすべき
? PHP5.3では非推奨(E_DEPRECATED)
? 他のmagic_quotes_xxx系も禁止
allow_url_include
? include()やrequire()の対象にURLを指定できる
? プログラムのバグや、DNSの改ざんなどによって、任
 意のプログラムを読み込ませられる可能性が
? 無条件でOFFにすべき
? PHP5.3では非推奨(E_DEPRECATED)
? 他のallow_url_xxx系も禁止
error_reporting
?なぜかE_NOTICEを切っている人が多い
?思わぬバグに気づかないことが多い
?ちゃんと手抜きせずに修正しよう
?可能であればE_STRICTやE_DEPRECATEDも
 ?CMSやフレームワークによっては対応していな
  いこともあるので难しい
つまりPHP5.3がいい
?危ない設定はE_DEPRECATED

?ここで紹介したもの以外にも
 E_DEPRECATEDなものがある(eregなど)

?エラーをちゃんと表示することが大事
よ廃   古
う墟   い




     PHP
なの
も    な
の    ん
     て
笔贬笔でセキュリティを真面目に考える
PHPには罠のような関数が沢山
?セキュリティ意識が低い時代に作られた

?PHP6くらいになったら消えてほしい

?少しずつE_DEPRECATED入りしている
strip_tags
?HTMLタグと思われるものを削除する

?誤動作する方法が沢山

?絶対に使ってはいけない

?htmlspecialcharsを使おう(詳しくは後で)
addslashes
? 文字列をクオートする
? DBにデータを入れる時に使いたくなる
? 実際には各RDBMSによって特殊な挙動があるため、
 脆弱性に繋がる可能性がある
? MySQLならmysql_real_escape_string、PostgreSQLな
 らpg_escape_stringを使用すべき
htmlspecialcharsと文字コード
? htmlspecialcharsの正しい使い方

?htmlspecialchars($var, ENT_QUOTES,
 'UTF-8');
? ENT_QUOTESを指定しないとシングルクオートが変
 換されない
? 文字コードを指定しないと、文字コードに起因する
 変換漏れが発生する
文字コード?
?Shift_JISで「表」は0x955C

?0x5C=¥

?0x955Cを、0x95と0x5Cで別々に処理する
 関数の場合、0x5C=¥記号を何らかの特殊
 記号と判定されてしまう可能性がある
<?php
// 「表」をSJISにする
$a = mb_convert_encoding('表', 'SJIS-win',
'UTF-8');
// addslashesでエスケープ
$b = addslashes($a);
// UTF-8に戻す
$c = mb_convert_encoding($b, 'UTF-8', 'SJIS-
win');
//出力
var_dump($c);


=> string(4) "表?"
htmlspecialcharsと文字コード
? htmlspcialcharsの例はまた別
? 詳細はhttp://www.tokumaru.org/d/20090930.html
  ? 「htmlspecialchars 文字コード」とかでぐぐれ

? PHP5.2.5から、不正な文字エンコーディングをチェッ
 クするようになった
? それ以前だと意味のない指定なので、必ず最新の
 PHPを
そもそもShift_JISは使うな
? 0x5C(¥)が文字コードに含まれるため危険
? Shift_JIS以外だから安全だというわけではないが、
 危険要素の多い文字コードなので避けるべき
? そもそもUTF-8でほとんどの場合は十分
? 携帯サイトで出力にShift_JISが要求される場合は、
 内部はUTF-8で処理し、入出力時にShift_JISで変換
 するのが望ましい
先行バイトによる問題
?マルチバイト文字コードの1バイト目だけ
を不正に出力することで、それ以降の文字
をマルチバイト文字の一部として認識さ
せ、本来の役割を破棄させることができる
?ブラウザ側で対応されていることが多い
(IE6とかはアウト)
文字コードとPHP
?文字コードを考慮されていない関数は危
 険

?ereg,fgetcsv,addslashes,strlen,etc…

?正規表現はpregを、mb_xxxがある関数は
 mb_xxxを使用すべき
標準関数だからといって
安心してはいけない


必ず公式ドキュメントなどで
確認を
笔贬笔でセキュリティを真面目に考える
SQLインジェクションとは
?本来正常に実行されるSQL文に、不正なコー
 ドを挿入することによって、本来意図しな
 いSQL文を実行し、攻撃する攻撃方法
?何かの文にDROP DATABASE xxx;とか追加し
 て、全データ削除したりとか
?他人のパスワードを不正に取得したり
SQLインジェクションの種類
?本来1つであるSQL文に、2つ目のSQLを追加
 して、任意のSQLを実行させる
?1つのSQLのパラメータ指定に、本来指定で
 きないパラメータを指定させることによ
 り、意図しないデータを取得したり操作し
 たりする
PHPとSQLインジェクション
?任意のSQLを挿入できるか?


$sql = 'SELECT * FROM   hoge WHERE foo = $foo';
$foo = '; DELETE   FROM hoge;';


// ここでSQL実行
?mysql_query … できない

?mysqli_query … できない

?pg_query … できる

?PDOStatement::execute … できない
問題なSQLインジェクション
?例えばSELECT文に穴があってパスワードを
入手できたりとか

?例えばDELETE文に穴があって全データ削除
できたりとか
回避方法
? プレースホルダが利用可能な場面では、極力
プレースホルダを使用する
? プレースホルダを使えない場面で、なるべく
文字列結合で値を渡さないようにする
? どうしても文字列結合で値を渡す必要がある
場合は、各DBMSに対応するエスケープ関数で
適切にエスケープする
プレースホルダ
$sql = 'SELECT * FROM hoge WHERE foo = ?;'

$stmt = $mysqli->prepare($sql);

$stmt->bind_param('s', $foo);

$stmt->execute( );
エスケープ関数で
$sql = 'SELECT * FROM hoge WHERE foo = %s;'

$new_sql = sprintf($sql, $mysqli-
>real_escape_string($foo));

$mysqli->query($new_sql);
テーブル名は特に危険
$sql = 'SELECT * FROM %s WHERE foo = 1;'

$new_sql = sprintf($sql, $foo);

$mysqli->query($new_sql);



// テーブル名なので'hoge'という指定はできない

// $foo に "hoge INNER JOIN …"とか入ると…?
DBMSと文字コード
?不正な文字コードを入れることによって変
 なことをさせる攻撃はDBMSにも存在する

?mysqlはUTF-8が3byteまでしか入らない(5.5
 で対応済)
MySQLのUTF-8
? ?????? や ?????? といった文字が入らない
? 入れようとするとwarningになるが、空として入る
 (errorにはならない)
? 例えばPHP側で入力チェックをして正常に通過して
 も、MySQL側には空文字として入ってしまう、という
 ことになる
? 文字チェックはDB側で行うことが必要
SQLインジェクションは
大規模な漏洩事件に
繋がりやすい
笔贬笔は関係ないので概要だけ
ケータイサイトを馬鹿にするな
?基本的には普通のサイトと同じ
?ケータイからソースが見えなくてもURLが
見えなくても、実際には同じ
?PCサイトと同じレベルのチェックが必要
 ?PCサイトより大変な部分も多い
 ?特に最近はJavaScriptも使える
滨笔アドレスで
   制限しておけば
    余裕だぜー




いや他にも
 脆弱性は
 あるし…

しかもそのIPアドレスリストちゃんと更新してる?
URLからのセッション乗っ取り
?Cookieが使えないケータイブラウザでは、
 セッションIDをURLにつけてやりとりする
 ことが多い
?外部サイトに飛ぶと、refererでセッション
 IDが漏れる
?そのセッションIDで接続すると…
URLからのセッション乗っ取り:対策
? できるだけCookieを使う
? セッションの有効期限を短めにする
? 外部サイトに飛ぶ場合は、必ず1ページ挟み、そこでは
  セッションIDは消す
? 検索エンジンに登録させない?登録させる場合は、
  canonical urlを指定する
? <link rel="canonical" href="http://example.com"/>
かんたんログインも怖い
?ちょっとのミスで攻撃方法が多数

?「限りなく防ぐ」方法は存在するが、「完璧に
 防ぐ」方法は存在しない

?Cookieが使用可能であれば極力Cookieを使
 用すべき
か盗個ち
もま人ょ
しれ情っ
れて報と
ないがし
いる た
   ミ
   ス
   で
笔贬笔でセキュリティを真面目に考える
既存のものを使うということ
? 「それなりに」信頼性がある
 ?特によく使われていて頻繁に更新されているもの
  ほど、安全性が高い(可能性が高い)

? 特にフレームワーク、CMSは、基礎的な脆弱性が
 起こらないような作りになっていることが多
 く、下手に自作するよりは安全なことが多い
しかし
?使い方を間違えれば脆弱性が生まれる

?最新のものを使わないと脆弱性が残ってい
る可能性がある
 ?特にCMSは、見た目で何を使っているかわかりや
 すいので、バージョンアップを怠ると狙われや
 すい
何が言いたいのか
? ライブラリやフレームワークなどは、ちゃんと
 メンテされているものであれば、(検証した上
 で)積極的に使おう
? バージョンアップされている場合は、(検証し
 た上で)対応していこう
? ライブラリやフレームワークを過度に信用せ
 ず、セキュリティチェックは必ず行おう
CakePHPの
securityコンポーネントにも
脆弱性があった
時代がありました
脆弱性以前の問題
? パスワードはちゃんと設定してますか?

? CMSやアプリの管理画面のURLはみんな知って
 る

? パスワードが簡単だと簡単に入られてしまう

? 管理画面はIPアドレス制限、BASIC認証などで、
 直接見られなくしておいたほうがいい
笔贬笔でセキュリティを真面目に考える
セキュリティに終わりはない
?いつ新しい攻撃方法が発見されるかわか
らない

?コンピュータの進化によって不可能が可能
になる場合も
 ?暗号とか
セキュリティ情報を追い続ける
?致命的な脆弱性にすぐ対応できるように

?→自分のサイトを守るために

?→みんなの個人情報を守るために
今回話せなかった内容
?XSS(クロスサイトスクリプティング)

?セッション関係

?CSRF

?PHPと関係ない話

?その他いろいろ
バグと脆弱性の境界
?脆弱性の根本はバグ
?バグ=脆弱性 ではない
?バグのないプログラムのほうが脆弱性が
少ない可能性が高い
?テストなどの、バグを減らすための手法も
実践すべき
バグが出ても…
? エラーは画面に表示しない!
? display_errors=OFF
? 開発中はONにしよう
? バグがないことが当然だが、最悪の場合のた
 め
  ?MySQLが突然死した時にうっかりパスワードが見
     えたりとか
セキュリティ情報の探し方
?php.net
  ?コピーサイトは見ない

?JPCERT/CC
?技術系ニュースサイト
 (slashdot,gihyo,@IT,etc…)
?その他個人ブログなど
とてもいい情報
? gihyo.jp「なぜPHPアプリにセキュリティ
 ホールが多いのか?」
  ? http://gihyo.jp/dev/serial/01/php-security
? IPA「安全なウェブサイトの作り方」
  ? http://www.ipa.go.jp/security/vuln/websecu
    rity.html
? 書籍「体系的に学ぶ 安全なWebアプリケー
 ションの作り方」
でも情報を探すのとか難しい
?札幌でー

?セキュリティのー

?勉強会とかー

?ないかなー
そうだ、せきゅぽろに参加しよう




 北海道情報セキュリティ勉強会 (通称:せきゅぽろ)
 http://secpolo.techtalk.jp/
笔贬笔でセキュリティを真面目に考える
LOCAL PHP部 参加者募集中!
?隔月で勉強会をしています
 ?次回は8月予定

?特に内容にこだわりはないので、「これを知
 りたい」とか教えてくれれば誰かが用意し
 てくれるかもしれません
?詳しくは「LOCAL PHP部」で検索!
画像提供(全てCC)

? http://www.flickr.com/photos/posteriormente/501245300
  6/
? http://www.flickr.com/photos/weightlifting/5065942769/
? http://www.flickr.com/photos/kentamabuchi/4616039938/
? http://www.flickr.com/photos/8mitsu/142336481/
? http://www.flickr.com/photos/sotome/2229496414/

More Related Content

笔贬笔でセキュリティを真面目に考える