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.

62 lines
1.4 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 简单的SQL 注入漏洞
## 漏洞攻击
```php
<?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
```sql
SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''
```
-- 是 SQL 注释符号,导致后续的 AND password = '' 被忽略。
查询变为:只要 username = 'admin' 成立即可登录,无需密码。
## 漏洞原因和处理策略
输入的字符串包含特殊字符这些特殊字符与原有的SQL查询字符串一起构成了意外的SQL。输入的数据只能当作字符串使用要使用转义。
## 漏洞修复
```php
<?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注入。