質問: PHP+MySQL PDOのセキュリティについて
回答: ※読み返してみると、プリペアドステートメントの概念をご存じないように見えたので、回答内容を大幅に修正しました。 > SELECT * FROM tablename WHERE id={$_POST['id']}; これでは駄目です。大幅に略しますが、基本は↓のような書き方になります。 $sth = $dbh->prepare('SELECT * FROM tablename WHERE id = :id;'); $sth->bindValue(':id', $_POST['id'], PDO::PARAM_INT); $sth->execute(); まずは、プリペアドステートメントの概念的な事を下記で理解し、大きなメリットが2点ある事を確認してください。 プリペアドステートメントは、mysqli_xxx系でも使用可能です。 ※mysql_xxx 系の関数は使わないようにしましょう。 プリペアドステートメントを正しく使えば、(※後述するような例外を除き)エスケープすべき文字はキチンとエスケープされます。 ただし、実運用時は $_POST['id'] の正当性をキチンとチェックするようにしてくださいね。 > 一応自動的にエスケープされてるみたいです。 もし、そのSQL文で本当にエスケープされていたのなら、それはおそらく magic_quotes_gpc によるものです。 var_dump(get_magic_quotes_gpc()); として true が出力されたら、magic_quotes_gpc が ON になっています。 PHP5.3で非推奨,5.4で削除された 無駄な混乱を招いたPHPの黒歴史的な機能ですので、OFF にする事を強く推奨します。 ※例外※ PHP5.3.6以前のPDO を MySQL で使う場合は、注意が必要です。 mysqli_real_escape_string() に相当する処理を行えません。 UTF-8で統一して運用されている場合のみ、 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' で回避可能です。 【注意】上記以外のケースで SET NAMES を使い文字コードを使用しているコードがあった場合、決して参考にしないようにしてください。 また、PHP5.3.6以降であっても、MySQL&SJISの組み合わせをWindows上で運用してはいけません。 「pdo set names」辺りでググれば、詳しい事が分かると思います。 PHPからDBに対し「◯◯の文字コードを使え!」と書いてもDBがその命令を認識してくれない場合に、上記のような問題が発生します。私が知らないだけで、他にも問題のあるバージョンがあるかもしれません。