ワードプレスのデータベース関連の処理に使用する$wpdb->prepare の使い方やその必要性について解説いたします。


SQLインジェクションを防ぐ$wpdb->prepare

SQLインジェクションとは、製作者の意図しない不正なデータをデータベースで実行させ、データベースの不正な書き込みや書き換えを可能としてしまう脆弱性のことです。

例えば下記のようなコードでは任意のSQL文をハッカーがネットワーク経由で送りこんでデータベースを書き換えてしまう事ができます。

$rows = $wpdb->get_var("SELECT * FROM ".$wpdb->prefix."posts where title = ".$_GET['title']);

この為$_GET[‘selectid’]の送信データをSQL文として解釈しないように前処理をしなければいけません。このことをエスケープ処理と言います。

$wpdb->prepare で送信されたデータをエスケープ処理

$wpdb->prepareはエスケープ処理されたSQL文を作成してくれる組み込み関数です。前述のコードの場合、下記のようなコードでエスケープ処理したSQL文を作成してくれます。

$query = $wpdb->prepare("SELECT * FROM ".$wpdb->prefix."posts where title = %s",$_GET['title']); //エスケープ処理
$rows = $wpdb->get_var($query);

このコードの%sの部分は、その後の引数と置き換えられ、かつエスケープ処理されて下記のようなSQL文になります。

SELECT * FROM wp_posts where title = '送信された文字列をエスケープ処理したもの'

%sは文字列であることを示し、”が自動的に付与されます。(%sを”で誤って囲ってしまったとしても2重にはなりませんが、’は自動付与されますのでない方がいいと思います)

”を自動付与されたくない場合は%1s(もしくは同じ意味の%1$s )を使います。

また数字の場合は%d(小数点を含む数字の場合%f)を使います。

$query = $wpdb->prepare("SELECT * FROM ".$wpdb->prefix."posts where title = %1s",$_GET['title']); 

↓

SELECT * FROM wp_posts where title = 送信された文字列をエスケープ処理したもの
※''が付与されません
$query = $wpdb->prepare("SELECT * FROM ".$wpdb->prefix."posts where ID = %d",$_GET['id']); 

↓

SELECT * FROM wp_posts where ID = 5
※送信された数字になります

WordPress ワードプレスのテーマやプラグインの修正カスタマイズ、コーディングのご依頼・ご相談はWPドクターまでお気軽にお送りください