INSERT INTO SELECT是否易受SQL注入?二次插入需注意什么?
问题解答
核心结论
user_name会被当作字符串处理:它是users表中定义为varchar类型的字段,数据库执行INSERT...SELECT时,会严格按照字段数据类型读取值,不会将其解析为SQL语句的一部分。- 预编译语句的核心作用是防范不可信外部输入(比如客户端提交的用户输入)被解析为SQL代码。当数据已存储到数据库后,属于可信数据,二次插入时不需要额外做参数绑定,只要保证当前查询的外部参数(比如示例中的
userId)用预编译处理即可。
补充说明的方案对比
直接使用INSERT...SELECT的预编译语句是安全且高效的:
$stmt = $db->prepare("INSERT INTO different_table (name) SELECT user_name FROM users WHERE userId = ?");
这个查询里唯一的外部变量是userId,通过预编译的?占位符处理,完全规避注入风险;user_name是数据库内部读取的字段值,会被自动作为字符串插入到different_table的name列,不会触发注入。
而“先查询再插入”的方案:
// 第一步查询 $stmt = $db->prepare("SELECT user_name FROM users WHERE user_id = 1"); // 第二步插入 $stmt = $db->prepare("INSERT INTO another_table (name) VALUES (?)"); $stmt->bindParam(1, $resultFromFirstQuery['user_name']);
虽然也能保证安全,但多了一次数据库交互,属于冗余操作,完全没必要。
内容的提问来源于stack exchange,提问作者RDU
相关产品推荐
相关产品推荐

