TOP書籍連動> 独自のエスケープ機能を呼び出す際の注意点
SQLインジェクション
SQLインジェクション

第1回:SQLインジェクションによるデータベース操作

著者:Ilia Alshanetsky   2006/1/18
前のページ  1  2   3  次のページ
独自のエスケープ機能を呼び出す際の注意点

   しかし、データベース独自のエスケープ機能を呼び出す前にマジッククォートの状態を確認することが大切です。マジッククォートが有効になっている場合、付け加えられたバックスラッシュ()をすべて取り除く必要があります。そうしないとユーザの入力はすでにエスケープされているので、二重にエスケープされてしまうことになり、エスケープ記号の意味がなくなってしまうのです。

   入力の安全性確保に加え、データベース特有のエスケープ関数はデータ破壊を防ぎます。例えば、MySQL拡張機能のエスケープ関数は、マルチバイト文字を認識してエンコードすることで、データが破壊されないことを保障します。

   ネイティブなエスケープ関数はバイナリデータの保存に対しても無意味になります。'エスケープ'しない場合は除きますが、バイナリデータはデータベース自体のストレージフォーマットと衝突する場合があって、これはテーブルやデータベース全体の破壊や喪失の原因となります。

   PostgreSQLのように、データベースの中にはバイナリデータをエンコードする専用の関数を提供しているものもあります。問題を起こす可能性のある文字をエスケープする機能に加え、このような関数は内部的にエンコードを適用します。例えば、PostgreSQLのpg_escape_bytea()関数はバイナリデータにBase64のようなエンコードを適用します。

// プレーンテキスト型のデータを使用する場合:
pg_escape_string($regular_strings);
// バイナリデータを使用する場合:
pg_escape_bytea($binary_data);

   バイナリデータをエスケープする仕組みは、データベースが本来サポートしていないマルチバイト言語を処理するのにも利用されます。(日本語のようなマルチバイト言語は1文字をあらわすのに複数のバイトを使います。これらの中には普通ならバイナリデータにしか使われないASCII の領域とかぶるものもあります。)

   バイナリデータのエンコードには欠点があります。データが完全一致以外の検索が行えないようにしてしまうのです。言い換えれば、LIKE'foo%'のような部分一致検索が使えない、ということです。これは、データベースに保存されているエンコードされた値が、必ずしも部分一致で指定した文字列にエンコードされているとは限らないためです。

   しかしアプリケーションのほとんどで、この制限は大きな問題にはなりません。というのは、部分検索は一般的に人が読んでわかるデータに対して行われ、イメージや圧縮ファイルのようなバイナリデータには行われないからです。


プリペアードステートメント

   データベース特有のエスケープ関数は役に立つものですが、すべてのデータベースでこのような機能が提供されているわけではありません。実際、データベース固有のエスケープ関数があるデータベースは比較的少数です。(この記事作成時は)MySQL、PostgreSQL、SQLite、Sybase、MaxDB の拡張機能でしか提供されていません。Oracle、Microsoft SQL Serverなどを含むその他のデータベースでは、別の解決策が必要になります。

   一番よく使われるテクニックが、データベースに入るデータをすべてBase64でエンコードするというもので、こうすることでどんな特殊な文字があっても蓄えられているデータが破壊されるなどのトラブルを防げます。しかしBase64エンコードを行うと約33%データ量が増えるので、より大容量のカラムやストレージが必要になります。

   さらに、Base64でエンコードされたデータにはPostgreSQLでのバイナリエンコードデータと同様の問題があります。LIKE を使った検索ができないのです。従って、入ってくるデータがクエリの構文に影響を与えないような、よりよい解決策が必要となります。

前のページ  1  2   3  次のページ


Ilia Alshanetsky
著者プロフィール
Ilia Alshanetsky
PHP開発チームの活動メンバーの1人であり、現在のPHP 4.3.X.のリリースマネージャー。また、オープンソース掲示板FUDフォーラム(http://fud.prohost.org/forum/)をはじめとする数多くのプロジェクトにも貢献している。


INDEX
第1回:SQLインジェクションによるデータベース操作要
  SQLインジェクションとは
独自のエスケープ機能を呼び出す際の注意点
  プリペアードクエリによるリスクの回避