You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1.4 KiB

简单的SQL 注入漏洞

漏洞攻击

<?php
// 用户输入(未过滤)
$username = $_POST['username'];
$password = $_POST['password'];
 
// 危险操作:直接拼接 SQL 查询
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $sql);
 
if (mysqli_num_rows($result) > 0) {
    echo "登录成功!";
} else {
    echo "用户名或密码错误!";
}
?>

如何绕过密码验证?

攻击者在 username 输入框中输入:

admin' --

实际执行的 SQL

SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''

-- 是 SQL 注释符号,导致后续的 AND password = '' 被忽略。 查询变为:只要 username = 'admin' 成立即可登录,无需密码。

漏洞原因和处理策略

输入的字符串包含特殊字符这些特殊字符与原有的SQL查询字符串一起构成了意外的SQL。输入的数据只能当作字符串使用要使用转义。

漏洞修复

<?php
// 使用预处理语句防止注入
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();
 
if ($result->num_rows > 0) {
    echo "登录成功!";
} else {
    echo "用户名或密码错误!";
}
?>

预使用PHP自带的SQL执行模板和绑定可以有效防止这种类型的SQL注入。