首页 >数据库 >mysql教程 >准备好的语句可以处理参数化表名以防止 SQL 注入吗?

准备好的语句可以处理参数化表名以防止 SQL 注入吗?

DDD
DDD原创
2025-01-23 17:56:09898浏览

Can Prepared Statements Handle Parameterized Table Names to Prevent SQL Injection?

准备好的语句:它们可以处理参数化表名称吗?

本文解决了预处理语句是否可以有效处理参数化表名以防止 SQL 注入漏洞的关键问题。

问题:

直接将用户提供的数据(包括表名)嵌入到 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( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

如果 .$new_table. 未正确清理,串联 $new_table 会使该函数容易受到 SQL 注入的攻击。

尝试参数化:

缓解此问题的常见尝试是尝试参数化表名称:

<code class="language-php">function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

现实:

不幸的是,这种方法失败了。 准备好的语句旨在防止

运行时值注入,而不是防止更改SQL查询本身的结构。 数据库解析器将表名解释为查询结构的一部分,而不是运行时参数。 用占位符替换它会导致无效的 SQL。

即使系统提供预准备语句模拟(例如 PDO),结果也将是无效查询(例如,

而不是 SELECT * FROM 'mytable')。SELECT * FROM mytable

解决方案:

处理用户提供的表名时防止 SQL 注入的唯一可靠方法是采用严格的

白名单。 这涉及预先定义允许的表名列表,并确保在查询中使用之前对照此白名单检查任何用户提供的表名。 切勿直接使用用户输入来构造涉及表名的 SQL 查询。

以上是准备好的语句可以处理参数化表名以防止 SQL 注入吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn