[PR]小規模ECサイトに最適なWAF、SiteGuard Lite
徳丸浩の日記
2011年03月29日
_PDO/MySQL(Windows版)の文字エンコーディング指定の不具合原因
前回のブログ「PHP5.3.6からPDOの文字エンコーディング指定が可能となったがWindows版では不具合(脆弱性)あり」にて、PHP5.3.6(本エントリ執筆時点での最新版)からPDOにてサポートされた文字エンコーディング指定がWindows版では正しく動作しないことを報告しました。Linuxでは正常に動作するので不思議だなという話になっていたのですが、千葉征弘さん(@nihen)が調べてくださった結果がtwitter上で発表されました(toggerによるまとめ「PHP5.3.6からPDOの文字エンコーディング指定が可能となったがWindows版では不具合にまつわる件」)。この件につき、当ブログでも報告します。
問題点の復習
PHP5.3.6以降のPDOでは、データベースに接続する際の文字エンコーディングを、接続文字列内にcharset=utf8等の形で指定することができます。PDO+MySQLの組み合わせの場合、Windows版のPHPからShift_JISでMySQLに接続する場合に、文字列のエスケープが正常に動かず、SQLインジェクション脆弱性の原因になっていました。
問題の原因
PHPのMySQLネイティブ・ドライバ(Mysqlnd)にバグがありました。ext/mysqlnd/mysqlnd_charset.cというファイル中のShift_JISの判定部分にバグがあります。
330 #define valid_sjis_head(c) ( (0x81 <= (c) && (c) <= 0x9F) && \ 331 (0xE0 <= (c) && (c) <= 0xFC)) 332 #define valid_sjis_tail(c) ( (0x40 <= (c) && (c) <= 0x7E) && \ 333 (0x80 <= (c) && (c) <= 0x7C))
[http://svn.php.net/viewvc/php/php-src/trunk/ext/mysqlnd/mysqlnd_charset.c?view=markup]
これだけだとどこが悪いのか分かりにくいかもしれませんが、cp932の場合の同様の処理と比べるとよく分かります。
213 #define valid_cp932head(c) ( (0x81 <= (c) && (c) <= 0x9F) || (0xE0 <= (c) && c <= 0xFC)) 214 #define valid_cp932tail(c) ( (0x40 <= (c) && (c) <= 0x7E) || (0x80 <= (c) && c <= 0xFC))
[http://svn.php.net/viewvc/php/php-src/trunk/ext/mysqlnd/mysqlnd_charset.c?view=markup]
全体のORをとらないといけないところをANDをとっているので、マクロvalid_sjis_headは常に偽を返します。このため、すべてのバイトが1バイト文字と認識されることになり、文字エンコードとしてLatin1(ISO8859-1)を指定した場合と同じ挙動となっています。これは、先の評価の結果と一致します。文字エンコーディングとしてcp932を指定した場合は正しく動作します。
また、333行目の末尾付近の0x7Cは、正しくは0xFCでしょう。ちょっと雑な作りというか、このあたり「やっつけ仕事」という印象を受けます。テストはしていないでしょうね。
なお、WindowsとLinuxで挙動が異なる理由は、WindowsではMySQLとの接続にMySQLネイティブ・ドライバ(Mysqlnd)が使用され、Linux(Unix)ではデフォルトでMySQLクライアント・ライブラリが使用されるからです(参照→PHP公式マニュアル)。上記のバグはMySQLネイティブ・ドライバ固有の問題なので、MySQLクライアント・ライブラリを使用する場合(Unix/Linuxのデフォルト設定)には影響しません。
どうすればよいか
では、どう書けばよいということですが、そもそもデータベースとの接続にShift_JISを使うこと自体が好ましくないので、結局前回の指摘と変わりません。再掲すると以下のようになります。
- 静的プレースホルダを用いる
- データベース接続の文字エンコーディングにはUTF-8を用いる
具体的には、以下のようにすると良いでしょう。
$dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', USERNAME, PASSWORD, array(PDO::ATTR_EMULATE_PREPARES => false)); // set names は必要ない // 後はプレースホルダによりSQLを呼び出す
ただし、既存のアプリケーションで、かつWindows環境でShift_JISを使っている場合には、文字エンコーディングとしてcharset=cp932を指定するとよいでしょう。その場合でも、array(PDO::ATTR_EMULATE_PREPARES => false)の指定により静的プレースホルダを用いることを強く推奨します。
- http://www.artparquet.ru/ ×90
- https://www.google.co.jp/ ×76
- http://blog.tokumaru.org/2011/08/pdo.html ×58
- http://mp3-narezki.ru/ ×42
- http://www.tokumaru.org/ ×39
- http://vivasan.swisstrade.ru/ ×39
- http://evoque.ru/ ×36
- http://www.kalb.ru/ ×34
- http://bimatoprost-careprost.com.ua/ ×32
- http://qiita.com/mpyw/items/b00b72c5c95aac573b71 ×29
- http://oren-cats.ru/ ×27
- http://www.onefilms.net/ ×25
- http://znakomstva-piter78.ru/ ×24
- http://ublaze.ru/ ×24
- http://psvita.ru/ ×24
- http://adult-picture.net/ ×24
- http://topshef.ru/ ×21
- http://mirzonru.net/ ×21
- http://kherson-apartments.ru/article_2.php ×21
- http://zakazfutbolki.com/ ×20
- http://loadka.ru/news ×20
- http://club-musics.ru/ ×16
- http://flash-igry.net/ ×15
- http://www.kiprinform.com/ ×14
- http://www.mymebel.by/ ×12
- http://winterior.com.ua/ ×12
- http://randecan.com/ ×12
- http://detalka.org/ ×12
- http://domhon.net/ ×11
- http://blog.tokumaru.org/2014/12/phpphp.html ×10
- http://blackwitchcraft.ru/ ×10
- http://youdesigner.kz/ ×9
- http://xn--h1ahbi.com.ua/ ×9
- http://uborka-doma.net/ ×9
- http://kolotiloff.ru/ ×9
- http://goshistory.org/ ×9
- http://emuparadise.ru/ ×9
- http://wetgames.ru/ ×8
- http://blog.tokumaru.org/2011/08/pdo.html?m=1 ×8
- https://www.google.com/ ×7
- http://www.kasholka.ru/ ×6
- http://sport-kosa.ru/ ×6
- http://pronekut.com/ ×6
- http://oklogistic.ru/ ×6
- http://mirmedinfo.ru/ ×6
- http://minecraft-neo.ru/ ×6
- http://delayreferat.ru/ ×6
- http://clash-clans.ru/ ×6
- http://blog.tokumaru.org/2014/12/phpphp.html?m=1 ×5
- http://www1.tokumaru.org/d/20110322.html ×4
- https://bugs.php.net/bug.php?id=54674 ×3
- http://www.stazher.com/ ×3
- http://www.protank.su/ ×3
- http://www.am-se.com/ ×3
- http://vbabule.net/ ×3
- http://sovetogorod.ru/ovosh_ogurec_virashivanie.ht... ×3
- http://snomer1.ru/ ×3
- http://pro-land.su/ ×3
- http://plastweb.ru/ ×3
- http://pereezd136.ru/ ×3
- http://naphukete.ru/ ×3
- http://myliveblog.ru/ ×3
- http://forum-engineering.ru/ ×3
- http://forms-mtm.ru/ ×3
- http://coldfilm.ru/ ×3
- http://www.php.net/ChangeLog-5.php ×2
- http://work.6bb.ru/ ×2
- http://translate.googleusercontent.com/translate_c... ×2
- http://livemane.webtalk.ru/ ×2
- http://finmasdelo.5bb.ru/ ×2
- https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.bing.com/ ×1
- https://search.yahoo.co.jp/ ×1
- http://www1.tokumaru.org/d/20110830.html ×1
- http://www.tokumaru.org:80/d/20100701-10.html ×1
- http://www.tokumaru.org/d/20110329.html ×1
- http://www.askapache.com/ ×1
- http://translate.googleusercontent.com/translate_c... ×1
- http://rhiz.jp/id/174.html ×1
- http://bugs.php.net/gh-pull-add.php?bug_id=54929 ×1
- http://blog.tokumaru.org/search?updated-max=2011-1... ×1
- http://blog.tokumaru.org/search?q=文字コード ×1
- http://blog.tokumaru.org/2017/01/joomla-34utf-84.h... ×1
- http://blog.tokumaru.org/2014_12_01_archive.html ×1
- http://archive.is/o/UR7L/http://www.tokumaru.org/d... ×1
- PDO_MYSQL エンコード ×2 / mysqlnd 文字化け ×2 / pdo 文字コード指定 ×1 / php エンコーディング指定 ×1 / pdo_pgsql プレースホルダ ×1 / pdo_mysql encode ×1 / php pdo 5c文字 回避 ×1 / pdo バグ ×1 / mysql_connect バグ ×1 / mysql クライアント エンコーディング 指定 ×1 / my健康手帳 ウインドウズ版 ×1 / myaqlの不具合 ×1
[PR]小規模ECサイトに最適なWAF、SiteGuard Lite
HASHコンサルティング株式会社
最近の記事
- 2011年08月30日
- 1. RSSフィードをリダイレクトします
- 2011年07月01日
- 1.
- 2011年03月29日
- 1. PDO/MySQL(Windows版)の文字エンコーディング指定の不具合原因
- 2011年03月22日
- 1. PHP5.3.6からPDOの文字エンコーディング指定が可能となったがWindows版では不具合(脆弱性)あり
- 2011年01月27日
- 1. CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例
- 2011年01月04日
- 1. escapeshellcmdの危険な実例
- 2011年01月01日
- 1. PHPのescapeshellcmdの危険性
- 2010年10月03日
- 1. 問題点の概要
- 2010年09月27日
- 1. 文字コードに起因する脆弱性を防ぐ「やや安全な」php.ini設定
- 2010年07月25日
- 1. ツッコミSPAM対策で、ツッコミ抜きのRSSフィードを用意しました
- 2010年07月01日
- 1. ぼくがPDOを採用しなかったわけ(Shift_JISによるSQLインジェクション)
- 2010年04月06日
- 1. PROXY(プロキシ)経由でのDNSリバインディングと対策
- 2010年04月05日
- 1. JavaアプレットのDNSリバインディングはJRE側で対策済みだった
- 2010年03月29日
- 1. DNSリバインディングによる無線LANパスフレーズの読み出しに成功
- 2010年03月25日
- 1. DNSリバインディングによるルータへの侵入実験
- 2010年02月22日
- 1. ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された
- 2010年02月12日
- 1. かんたんログイン手法の脆弱性に対する責任は誰にあるのか
- 2010年01月18日
- 1. iモードブラウザ2.0のXMLHttpRequestでPOSTデータの扱いが困難になった
- 2009年10月19日
- 1. quoteメソッドの数値データ対応を検証する
- 2009年10月14日
- 1. htmlspecialchars/htmlentitiesはBMP外の文字を正しく扱えない
- 2009年10月09日
- 1. htmlspecialcharsのShift_JISチェック漏れによるXSS回避策
- 2009年09月30日
- 1. htmlspecialcharsは不正な文字エンコーディングをどこまでチェックするか
- 2009年09月24日
- 1. SQLの暗黙の型変換はワナがいっぱい
- 2009年09月18日
- 1. 文字エンコーディングバリデーションは自動化が望ましい
- 2009年09月14日
- 1. 既にあたり前になりつつある文字エンコーディングバリデーション
- 2009年08月05日
- 1. 携帯JavaScriptとXSSの組み合わせによる「かんたんログイン」なりすましの可能性
- 2009年03月28日
- 1. IPAは脆弱性の呼び方を統一して欲しい
- 2009年03月27日
- 2009年03月11日
- 1. U+00A5を用いたXSSの可能性
- 2008年12月22日
- 1. JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性