准备好的语句和表名安全性:严格检查
许多开发人员依靠mysqli_stmt_bind_param
来防止SQL注入漏洞。 然而,这种方法在尝试参数化表名称时会带来挑战。
考虑这个例子:
<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中文网其他相关文章!