konekto Inc with PHP , MySQL コネクト株式会社 技術情報コンテンツ


[[セキュリティ指針]]

SQLインジェクション対策

説明

SQLインジェクションとは、データベースへの登録につながるフォーム入力値に、特殊記号の使用により意図しないSQLを埋め込まれることによって発生する問題を指す。

被害例

例えば以下のような、SQLを実行するSQLがあったとする。

$id_no = $_POST['userid'];
$sql = "select * from hoge where id=\"$id_no\";"
excec($sql);

ユーザからの、入力である$_POST['userid']数値だけが入っていると決め付け入力を確認していない場合に、たとえば$_POST['userid']が、"10";DELETE * FROM hoge;"などといった入力が行われると、データベースの種類によっては、hogeテーブルすべてのデータが消滅してしまう。

また、不正な入力により本来アクセス権のない情報へのアクセスを許容してしまう可能性がある。

対策

以下の文字列をサニタイズする。

 変換前   変換後
 -------  --------
 '        "
 ;        削除する
 --       "
 \        \\
 %        \%
 _        \_
  • バインドメカニズムを利用する。

コーディング手法

  • PEARのDBクラスを用いる場合
    $dbc = DB::connect($dsn); // PEAR DB を使って接続
    $sql = "select * from foo where bar=?"; // 可変箇所はプレースホルダ(「?」)を記述
    $vars = array($str); // プレースホルダの順に配列に値を格納
    $rows = $dbc->getAll($sql, $vars); // プレースホルダに自動的に値が挿入される
    ※PEARのDBクラスを用いる事で、使用するDBMSの種類に依存しないサニタイズが可能です。
  • MySQLの場合はmysql_escape_string関数を使用する。
    $sql = "select from foo where name like='%" . mysql_escape_string($key) . "%'";
  • PostgreSQLの場合はpg_escape_string関数を使用する。
  • 上記被害例のでDBがMysqlの場合
    $id_no = $_POST['userid'];
    if (!is_numeric($id_no)){
      die('不正な値です。');
    }
    $sql = "select * from hoge where id=\"mysql_escape_string($id_no)\";";
    excec($sql);

最終更新のRSS