php中sql注入漏洞示例 sql注入漏洞修复


### SQL注入漏洞示例

在PHP中,SQL注入漏洞通常发生在直接将用户输入拼接到SQL查询语句中,而没有进行适当的过滤或预处理。以下是一个简单的示例,展示了如何错误地处理用户输入,导致SQL注入漏洞:


<?php
$username = $_GET['username']; // 假设这是从URL中获取的用户名

// 错误的做法:直接将用户输入拼接到SQL查询中
$query = "SELECT * FROM users WHERE username = '$username'";

// 执行查询...(这里省略了数据库连接和查询执行的代码)

// 注意:这里存在SQL注入风险,因为$username的值可以被恶意用户控制
?>

如果攻击者将`username`的值设置为`' OR '1'='1`,那么生成的SQL查询将变为:


SELECT * FROM users WHERE username = '' OR '1'='1'

这个查询将返回`users`表中的所有记录,因为`'1'='1'`总是为真。

### SQL注入漏洞修复

为了修复SQL注入漏洞,应该使用预处理语句(Prepared Statements)和参数化查询。预处理语句不仅可以防止SQL注入,还可以提高查询性能。以下是使用PDO(PHP Data Objects)扩展来修复上述示例的方法:


<?php
try {
    $pdo = new PDO('mysql:host=localhost;dbname=your_database', 'username', 'password');
    // 设置PDO错误模式为异常
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $username = $_GET['username'];

    // 使用预处理语句和参数化查询
    $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
    $stmt->bindParam(':username', $username, PDO::PARAM_STR);
    $stmt->execute();

    // 获取查询结果...(这里省略了结果处理的代码)

} catch(PDOException $e) {
    echo "数据库错误: " . $e->getMessage();
}
?>

在这个修复后的示例中,`$username`变量被绑定到预处理语句的参数上,而不是直接拼接到SQL查询中。这样,即使`$username`包含恶意代码,它也不会被解释为SQL的一部分,从而避免了SQL注入的风险。