今のところの結論
- データベースにも依るだろうが、そもそもプリペアドステートメントが使えないSQL文法がある。なので、「PDOドライバ毎に静的プレースホルダ/動的プレースホルダのどちらを使っているか」というのは問題設定に無理があるようだ。「どのPDOドライバも、どちらのプレースホルダも使っている」と思っておくのが妥当なのかもしれない。もしそうであるなら、「セキュリティ的に静的プレースホルダより信頼性の劣る動的プレースホルダを完全に避けるのは難しい」ということになりそうだ。
以下は、上記の結論を書く前に少し調査した内容だが記録のために残しておく。
MySQL (PDO_MYSQL)の場合
PDO_MYSQL は、MySQL 4.1 以降に存在するプリペアドステートメントを ネイティブにサポートしているという利点があります。 古いバージョンの mysql クライアントライブラリを使用している場合は、 PDO がこの機能をエミュレートします。
- 上記では、プリペアドステートメントが使えない SQL文法については触れられていない。PDO内でエミュレートしている?
その他のデータベース用ドライバ
- 各データベース用ドライバが、データベースに実装されているプリペアドステートメント機能を利用しているのかどうかは、php.net に載っていない?見付からなかった。
参考
- PHP: PDO ドライバ – Manual
- MySQL :: MySQL 5.7 Reference Manual :: 13.5 SQL Syntax for Prepared Statements
- https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html
- “SQL Syntax Allowed in Prepared Statements” という項目がある。
- 漢(オトコ)のコンピュータ道: SQLインジェクション対策に正解はない