请问我编写的该简单函数是否足以防范SQL注入攻击?
你的代码能否防范SQL注入?咱们来拆解分析
首先得揪出你代码里的几个关键问题,再聊聊SQL注入的正确防护思路:
1. encr函数的致命漏洞
你的encr函数做了trim、stripslashes、htmlspecialchars操作,但它没有返回值!这意味着$sub_username和$sub_password实际上是null,直接会导致SQL查询出错,更别说防注入了。就算你给函数加上return $data;,这些操作也和防范SQL注入无关:
htmlspecialchars是用来防XSS攻击的,对SQL注入没作用;stripslashes在现代PHP环境下(magic_quotes_gpc早已被移除)完全没必要,反而可能破坏合法输入的内容。
2. mysqli_real_escape_string的局限性
虽然mysqli_real_escape_string能转义SQL中的特殊字符,但你把它的输出又传给了encr(假设encr有返回值),会导致转义后的字符被二次处理,反而可能破坏防护效果。更关键的是:
- 这种字符串拼接SQL的方式,依赖于严格匹配的字符集配置(如果数据库连接字符集和输入字符集不匹配,escape功能可能直接失效);
- 它本质上还是把数据和SQL结构混在一起,不如**参数化查询(预处理语句)**从根源上安全。
3. 正确的SQL注入防护方案:参数化查询
从根本上避免SQL注入的方式是使用预处理语句,把SQL结构和用户输入的数据分开传递,数据库会自动处理数据的安全注入。给你写个修正后的示例:
// 先获取并清理用户输入(仅做trim即可) $username = trim($_POST['username']); $password = $_POST['password']; // 使用预处理语句:?是参数占位符 $sql = "SELECT password FROM login WHERE username = ?"; $stmt = mysqli_prepare($conn, $sql); // 绑定参数:"s"表示字符串类型,对应后面的$username mysqli_stmt_bind_param($stmt, "s", $username); // 执行查询 mysqli_stmt_execute($stmt); // 获取结果集 $result = mysqli_stmt_get_result($stmt); // 处理登录逻辑(假设数据库存的是password_hash生成的哈希值) if ($row = mysqli_fetch_assoc($result)) { if (password_verify($password, $row['password'])) { // 登录成功逻辑 echo "登录成功!"; } else { echo "密码错误"; } } else { echo "用户不存在"; }
额外的密码安全提示
你用encr处理密码的方式是错误的:永远不要自己写加密函数处理密码,应该用PHP内置的password_hash()生成安全的哈希值存在数据库,用password_verify()验证,这才是符合安全标准的密码存储方式。
内容的提问来源于stack exchange,提问作者ahmedg
相关产品推荐
相关产品推荐

