WordPressを3.5にアップデートすると、Warning: Missing argument 2 for wpdb::prepare(), called in 〜(ファイル名)
というエラーメッセージが出る場合があります。
公式マニュアルのClass Reference/wpdbを見ると、「プレースホルダを含むSQLクエリ」と、「プレースホルダに代入する値」を引数として取ります。プレースホルダに代入する値は一つとは限らず、複数のこともあります。
なので、wpdb::prepare()
を使う場合は、最低2つの引数が必要となります。ただし、WordPress3.4.x以前は、引数が不足していてもエラーが出ない仕様になっていました。(構文エラーにならないですが)引数一つは間違いなのは、WordPress3.4.x以前から共通しています。
この部分の引数が適切でない場合は、SQL自体に脆弱性のある可能性が高いため、引数1つの場合に警告を出すことが、http://core.trac.wordpress.org/ticket/22262で提案されました。次のリリースではnotice(注意)メッセージにする案も出されていましたが、最終的には警告になりました。(このチケットの時点では、3.5リリースまで一ヶ月以上の期間があったので、適切だったと思います。)このため、プラグインやテーマでwpdb::prepare()
の引数が不足している場合、Warning: Missing argument 2 for wpdb::prepare(), called in 〜
というエラーメッセージが出ます。
開発ブログhttp://make.wordpress.org/core/2012/12/12/php-warning-missing-argument-2-for-wpdb-prepare/では、「とりあえずエラー抑制しておく」という記述があるのですが、これはまずい対処だと思います。
wpdb::prepare()
の使い方が変である、ということは、そのプラグイン/テーマの作者は、プリペアードクエリやプレースホルダを理解していない可能性が高いです。理解しないまま使う、ということは非常に危険ですね。SQLインジェクション脆弱性のあるプラグイン/テーマの可能性は結構高いと思います。なので、当該プラグイン/テーマの使用を控えることをお勧めします。少なくとも、第二引数にダミーデータを入れて対応した、というプラグイン/テーマは避けるべきです。第二引数にダミーデータを入れること自体は危険性を高めませんが、脆弱性対策にはなりません。このような対応をしている(wpdb::prepareの使い方が間違っている)プラグイン/テーマは、セキュリティホールのある可能性が高いです。
SQLインジェクションまで書いてあるWordPress書籍は、Professional WordPress Plugin Developmentがあります。少し古いですが、プラグイン開発者は読んでおく価値があると思います。
追記:akismetプラグインにwpdb::prepare()
の使い方間違いがあったようですが、2.5.7では解消されています。 http://plugins.trac.wordpress.org/changeset/637848/akismet/trunk/akismet.phpをごらんください。適切な対処方法が確認できます。
[…] 詳細は水野さんのブログに書かれていますのでそちらを参照してください。 https://ounziw.com/2012/12/20/wpdb-prepare/ […]
[…] こちらの記事に かなり厳しいことが書かれていますので、読んでみてください。 記事内の「とりあえずエラー抑制しておく」の事は確かに良くないと思います。 (不具合が潜在してしまうだけだし…) […]