[PR]小規模ECサイトに最適なWAF、SiteGuard Lite
徳丸浩の日記
2009年10月19日 [Perl][PHP][SQL]
_quoteメソッドの数値データ対応を検証する
このエントリでは、PerlのDBI、PHPのPDO、MDB2にて用意されているquoteメソッドが数値データをどのように扱えるかを検証しました。結論としてMDB2が合格、それ以外は不合格で、とくにDBD::mysqlを使用した場合、脆弱性といってもよいような結果となりました。
概要
DBI、PDO、MDB2は、いずれもデータベースアクセスを抽象化したモジュール(クラス)であり、汎用的な記述によりさまざまなデータベースを利用できるように工夫されています。これらモジュール(クラス)にはquoteというメソッドが用意されています。DBIのquoteメソッドの呼び出し例を示します。
my $dbh = DBI->connect('DBI:mysql:dbname:localhost', 'user', 'pass'); print $dbh->quote("a\\'"); # 「a\'」という文字列を指定 【処理結果】 'a\\\''
ごらんのように、あるいはquoteという名称が示すように、これらメソッドは入力データをSQL文字列リテラルとしてエスケープした上で、シングルクオートでくくります。SQLの文字列リテラルのエスケープ方法はデータベースソフトウェア依存であり、MySQLの場合はシングルクオートとバックスラッシュをエスケープしますが、標準SQLではシングルクオートのみです*1。quoteメソッドを利用することにより、データベースの種類を自動的に考慮して、SQLを安全かつ簡便に動的組み立てできます。
さて、quoteメソッドには省略可能な第二引数があり、データの型を指定できるようになっています(デフォルトは文字列型)。以下に、整数型を指定した場合の呼び出し方を示します。
DBI: $dbh->quote($n, SQL_INTEGER) PDO: $dbh->quote($n, PDO::PARAM_INT) MDB2: $dbh->quote($n, 'integer')
ごらんのように、呼び出し方はほとんど同じです。では、この処理結果は、どうなる *べき* でしょうか。私の過去の日記「数値項目に対するSQLインジェクション対策のまとめ」や「SQLの暗黙の型変換はワナがいっぱい」で説明したように、SQLは本来厳格な型をもった言語であり、数値リテラルをシングルクオートで囲むことは好ましくありません。したがって、quoteメソッドに数値型を指定した場合は、たんなる数値が返るべきだと考えます(SQL組み立てが目的なので、型は文字列型でもよい)。そこで、入力データのサンプルとして「1a\'」を第一引数に、整数型指定を第二引数としてquoteメソッドを呼び出してみました。
DBI: $dbh->quote("1a\\'", SQL_INTEGER) PDO: $dbh->quote("1a\\'", PDO::PARAM_INT) MDB2: $dbh->quote("1a\\'", 'integer')
結果は以下のようになります。PDOとMDB2は、MySQLとPostgreSQLで同じ結果です。
モジュール名 | 結果 |
---|---|
DBI(DBD::mysql) | 1a\' |
DBI(DBD::PgPP) | '1a\\\'' |
PDO | '1a\\\'' |
MDB2 | 1 (int型) |
先に書いた「あるべき結果」になったのはMDB2だけでした。PDOとDBD::PgPPは、文字列型として指定したのと同じ結果であり、SQLインジェクション対策として機能しますが、なんのためにわざわざ整数型を指定したのかわかりません。DBD::mysqlはエスケープもクオートもしていないので、入力として「1 union select table_name from information_schema.tables」を与えられると、一覧表を表示する画面でテーブルの一覧が表示させられるような結果となります。これはまずい。現実問題として、何もしないのでは、わざわざquoteをメソッドを呼ぶ動機がありません。
また、文字列としてエスケープする方法も、先のエントリで説明したように、さまざまな副作用がありますので、quoteメソッドを使うよりは、SQL呼び出し直前でバリデーションするか、sprintfで%dの書式を与えることで、数値のみが出力されるように制限する手法が考えられます。
今回の調査で、MDB2のquoteメソッドは、わりといい線行っていると思いました。MDB2のquoteでは、'decimal'という指定もできるのですが、20桁程度の数値を与えても、破綻なく動作します。
入力 | 出力 |
---|---|
123456789012345678901 (文字列型) | 123456789012345678901 (文字列型、クオートなし) |
1a2b3 (文字列型) | 123 (文字列型、クオートなし) |
'1a2b3'に対する結果が「123」となるところ、「サ、サニタイズかよ」と思ってしまいますが、まぁ数値としてのバリデーションは入り口でやるとして、SQL発行時の「最後の砦」としては、まぁ許容できる範囲ではないかと思います。「例外を発生させるべきじゃないの?」と思うのですが、他のモジュールのだめさ加減との比較では上出来でしょう。
なお、DECIMAL型の場合に、文字列型で結果を返すのは妥当な処理です。PHPに標準で用意されているintegerやfloatでは、DECIMALの桁数(MySQLでは最大65桁、PostgreSQLでは最大1,000桁)を表現するのに十分なビット長がないからです。演算はどうするのだという疑問がありそうですが、DBの性能に余裕があればSQLで演算するという手もありますし、BCMath 任意精度数学関数を使う手もあります。BCMathは文字列型のままで数値演算ができます。
まとめ
DBI、PDO、MDB2のquoteメソッドについて、第二引数明示により数値として処理する内容について検証しました。期待どおり動作するのはMDB2であり、一方DBD::mysqlではなにもしていないので脆弱性対策としては使えないことがわかりました。
また、今回のエントリでは示していませんが、PDOは処理が高速なために人気があるものの、内部処理をつっこんで見ていくと、不安が出てきました。その内容については別途何かの形で発表したいと思いますが、現時点では、id:moriyoshiさんの以下のエントリが参考になると思います。
*1 詳細については、「 SQLのエスケープ再考 」および「SQLエスケープにおける「\」の取り扱い 」に詳しく書きましたので参考になさってください
- https://www.google.co.jp/ ×1022
- http://blog.tokumaru.org/2011/08/pdo.html ×299
- http://www.tokumaru.org/ ×86
- http://blog.tokumaru.org/2015/05/php_18.html ×30
- https://www.google.com/ ×27
- http://blog.tokumaru.org/ ×26
- http://blog.tokumaru.org/2015/05/php_18.html?m=1 ×17
- http://blog.sarabande.jp/post/28651278729 ×9
- http://d.hatena.ne.jp/ockeghem/20090711/p1 ×7
- http://blog.tokumaru.org/2011/08/pdo.html?m=1 ×7
- https://www.bing.com/ ×6
- http://ysearch.luna.tv/search.aspx?keyword=perl qu... ×4
- http://blog.tokumaru.org/search?updated-max=2015-0... ×4
- http://blog.tokumaru.org/search?updated-max=2015-0... ×4
- http://blog.tokumaru.org/2015_05_01_archive.html ×3
- http://search.fenrir-inc.com/?q=sql php quote&hl=j... ×3
- http://www1.tokumaru.org/d/20110101.html ×2
- http://araistudy.g.hatena.ne.jp/czk-htn/20100117/1... ×2
- https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.google.co.kr/ ×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.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.google.co.jp/url?sa=t&rct=j&q=&esrc=s&... ×1
- https://www.google.com.ph/ ×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.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/search?q=$dbh- quote&qs=CE&pq... ×1
- https://search.yahoo.co.jp/ ×1
- http://tumix.softwarelibre.org.pe/index.php?option... ×1
- http://t.umblr.com/ ×1
- http://t.co/WciV2kT8Ff ×1
- http://t.co/G62vsj9icy ×1
- http://sec.laboradian.com/php/?preview_id=12&previ... ×1
- http://search.fenrir-inc.com/?q=quote perl&hl=ja&s... ×1
- http://search.fenrir-inc.com/?q=PDO quote のみ使いたい&h... ×1
- http://search.fenrir-inc.com/?hl=ja&channel=sleipn... ×1
- http://r.duckduckgo.com/ ×1
- http://outlook.activet.co.jp/owa/redir.aspx?C=Rq1W... ×1
- http://outlook.activet.co.jp/owa/redir.aspx?C=MC9e... ×1
- http://kjunichi.cocolog-nifty.com/misc/ ×1
- http://blog.tokumaru.org/search?updated-min=2015-0... ×1
- http://blog.tokumaru.org/search?updated-max=2015-0... ×1
- http://blog.tokumaru.org/2017/01/joomla-34utf-84.h... ×1
- http://blog.tokumaru.org/2015/05/php_18.html?fb_re... ×1
- http://blog.tokumaru.org/2011_08_01_archive.html ×1
- http://blog.sarabande.jp/tagged/php/page/8 ×1
- http://api.twitter.com/1/statuses/show/40260622461... ×1
- sql quote ×11 / perl dbi quote ×11 / perl quote ×9 / dbh quote ×6 / quote処理 ×4 / SQL server quote mysql ×2 / quote メソッド ×2 / perl sqlインジェクション ×2 / perl dbi エスケープ ×2 / dbi dbh quote ×2 / quote php integer ×2 / QUOTE SQL ×2 / Perl DBI quote ×2 / DBI quoteメソッド ×2 / perl postgresql quote ×2 / perl QOUTE ×2 / perl dbi quote in ×2 / perl quote data ×2 / quote sql ×2 / DBI quote ×2 / php quote ×2 / quote mdb2 ×1 / quoteメソッド ×1 / quote mysql ×1 / php quote integer ×1 / quote method ×1 / php SQL_QUOTE ×1 / perl ip quote ×1 / perl エスケープ quote ×1 / perl エスケープ処理 quote ×1 / pdo サニタイズ ×1 / java sql quote ×1 / SQL_QUOTE ×1 / SQL quoteメソッド ×1 / Quote メソッド ×1 / QUOTEメソッド ×1 / PDO quote ×1 / PDO サニタイズ ×1 / quote perl ×1 / DBI クオート ×1 / 型変換 DB Perl ×1 / クオートsql ×1 / {quote} SQL 動作 ×1 / perl blockquote ×1 / $dbh->quote ×1 / DBI quote perl ×1 / perl dbi 脆弱性 ×1 / PHP quote ×1 / perl SQLite 不具合 ×1 / perl クオート ×1 / pdo php perl dbi ×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インジェクションの可能性