使用Prepared Statements防SQL注入:更新操作是否仍需使用?
当前实现存在严重的SQL注入风险,完全不安全!
你的代码直接把用户可控的输入($note和$id)拼接到SQL语句里,这是SQL注入的高危操作——不管是查询、插入还是更新操作,只要涉及用户输入,都必须用预处理语句(Prepared Statements)来防护,原因很直观:
- 针对
$note:如果用户在文本框输入类似'); DELETE FROM table; --这样的内容,你的SQL会变成:
这会直接触发恶意删除操作(如果数据库权限允许的话)。UPDATE table SET note = ''); DELETE FROM table; --' WHERE id = 1 - 针对
$id:虽然是隐藏字段,但用户可以通过浏览器开发者工具、POST请求篡改等方式修改这个值,比如把id改成1 OR 1=1,你的SQL会变成:
这会更新表中所有行的UPDATE table SET note = 'xxx' WHERE id = 1 OR 1=1note字段,后果非常严重。
必须调整的两个关键点:
1. 改用预处理语句执行UPDATE操作
修改你的xtest.php代码,使用mysqli的预处理机制,彻底把SQL逻辑和用户数据分离:
$action = $_POST['btSubmit'] ?? ''; if ($action == "Submit") { // 先做基础输入验证,比如确保id是整数 $id = filter_input(INPUT_POST, 'hidden_id', FILTER_VALIDATE_INT); $note = filter_input(INPUT_POST, 'note', FILTER_SANITIZE_FULL_SPECIAL_CHARS); if (!$id) { echo "无效的ID参数"; exit; } // 准备带占位符的SQL语句 $sql = "UPDATE table SET note = ? WHERE id = ?"; // 初始化预处理语句 $stmt = $link->prepare($sql); // 绑定参数:s代表字符串类型,i代表整数类型 $stmt->bind_param("si", $note, $id); // 执行更新操作 if ($stmt->execute()) { echo "Record updated successfully"; } else { echo "Error updating record: " . $stmt->error; } // 关闭语句和数据库连接 $stmt->close(); $link->close(); }
2. 修复HTML中的XSS风险
你的HTML里直接把{$row['note']}输出到input的value属性中,如果note字段包含特殊字符(比如<script>、引号),会引发XSS攻击。需要用htmlspecialchars做转义处理:
<form method='post' action='xtest.php'> <input type='hidden' name='hidden_id' value='<?php echo htmlspecialchars($row['id'], ENT_QUOTES); ?>'> <td><input type='text' name='note' id='note' value='<?php echo htmlspecialchars($row['note'], ENT_QUOTES); ?>'></td> <td><input type='submit' name='btSubmit' value='Submit'></td> </form>
补充说明
预处理语句的核心是让数据库先解析SQL的结构,再传入用户数据,这样数据库会把数据当作纯数据处理,不会当作SQL逻辑的一部分执行,从根源上避免了SQL注入。不管是哪种数据库操作(增删改查),只要涉及用户可控的输入,都应该用预处理语句,没有例外。
内容的提问来源于stack exchange,提问作者Erik Auranaune
相关产品推荐
相关产品推荐

