プリペアドステートメントとテーブル名のセキュリティ: 重要な検査
多くの開発者は、SQL インジェクションの脆弱性を防ぐために mysqli_stmt_bind_param
に依存しています。 ただし、このアプローチでは、テーブル名をパラメーター化しようとすると課題が生じます。
次の例を考えてみましょう:
<code class="language-php">function insertRow($db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol) { $statement = $mysqli->prepare("INSERT INTO " . $new_table . " VALUES (?,?,?,?,?,?,?);"); mysqli_stmt_bind_param($statement, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol); $statement->execute(); }</code>
これは変数をバインドすることで SQL インジェクションを軽減しようとしますが、テーブル名 $new_table
は脆弱なままになります。 準備されたステートメント内で $new_table
のプレースホルダーを使用できますか?
いいえ。 データベースの準備済みステートメントは、テーブルまたは列の識別子ではなく、値 のパラメーター バインディングのみをサポートします。 これは、テーブル名が SQL ステートメントの構造と有効性に不可欠であるためです。動的に変更すると、無効な SQL が発生する可能性があります。
より柔軟なプレースホルダーの使用を提供する PDO のようなデータベース インターフェイスを使用しても、テーブル名を直接置換しようとすると、無効な SQL が発生します。
<code class="language-sql">SELECT * FROM ?</code>
正しいアプローチには、文字列補間の使用が含まれます。
<code class="language-php">SELECT * FROM {$mytable}</code>
ただし、これには、厳格なテーブルのホワイトリストという重要なセキュリティ対策が必要です。 悪意のある入力によるデータベースの侵害を防ぐために、許可されたテーブル名の事前定義されたリストに対して $mytable
を常に検証してください。 テーブル名のセキュリティについては、準備されたステートメントのみに依存しないでください。
以上がプリペアドステートメントはテーブル名を安全にパラメータ化できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。