phpmysql注入漏洞防护转载x1
发布日期:2021-05-28 21:22:26 浏览次数:18 分类:精选文章

本文共 2893 字,大约阅读时间需要 9 分钟。

PHP安全:SQL注入漏洞防护

SQL注入是一种严重的安全漏洞,能够直接危及数据库和应用的安全性。作为开发者,我们需要采取有效措施来防止这种攻击。以下将详细介绍如何在PHP中使用MySQL预编译技术和传统防护方法来应对SQL注入威胁。

1. MySQL 预编译处理

MySQL 提供了预编译功能,可以有效隔离和执行 SQL 语句,避免恶意输入直接执行成代码。预编译分为三步:编译、执行和释放。

  • 编译准备语句

    使用 prepare 语句将 SQL 语句编译并存储为准备语句。例如:

    prepare test from 'insert into hacker select ?, ? ';

    返回的状态可以被引用并重复使用。

  • 执行预编译语句

    将参数绑定后执行预编译语句。例如:

    execute test using @name, @email, @password, @status;

    使用 execute 语句以 @variable 格式传递参数。

  • 释放和管理预编译语句

    使用 deallocate prepare test 释放预编译语句,避免占用资源。可以通过设置 max_prepared_stmt_count 控制全局预编译语句的数量:

    set @global.max_prepared_stmt_count = 100;
  • 预编译防护的优势

    预编译将 SQL 语句和数据分开处理,避免了跨 Injection 攻击。通过工具如Wireshark,可以监控预编译和参数的网络传输情况。


  • 2. PHP 中的预编译防护

    在 PHP 中,推荐使用 PDO(PHP 数据对象扩展)或 MySQLi 来实现预编译处理。

    2.1 PDO 的预编译示例

    PDO 提供了对预编译的支持,通过设置适当的属性可以确保服务器端真正执行预编译语句。

    $dns = 'mysql:dbname=safe;host=127.0.0.1';try {    $pdo = new PDO('pdo://'.$dns, 'root', '');    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);        $pdo->query('set names utf8');    $sql = 'insert into hacker(name, email) values(:name, :email)';        $stmt = $pdo->prepare($sql);        $name = 'hacker';    $email = 'safe@ptpress.com.cn';        $stmt->bindParam(':name', $name, PDO::PARAM_STR);    $stmt->bindParam(':email', $email, PDO::PARAM_STR);    $stmt->execute();        if ($stmt->errorCode() == 0) {        echo "数据插入成功";    } else {        echo "错误:" . $stmt->errorInfo();        print_r($stmt->errorInfo());    }        $stmt->close();    $pdo->close();} catch(PDOException $e) {    echo "数据库连接失败:" . $e->getMessage();}

    2.2 MySQLi 的预编译示例

    MySQLi 提供了与 PDO 相似的功能,同样支持预编译技术。

    $mysqli = new mysqli('localhost', 'root', '', 'safe');if ($mysqli->connect_errno) {    printf("Connect failed: %s", $mysqli->connect_error);    exit();}$mysqli->query('set names utf8');$sql = 'insert into hacker(name, email) values(?, ?)';$stmt = $mysqli->prepare($sql);$name = 'hacker';$email = 'safe@ptpress.com.cn';$stmt->bind_param('ss', $name, $email);$result = $stmt->execute();if (!$result) {    echo "错误:" . $mysqli->error;} else {    echo "数据插入成功";}$stmt->close();$mysqli->close();

    2.3 预编译的核心优势

    预编译的核心作用是通过将 SQL 语句和数据分离,从根本上杜绝 SQL 注入威胁。客户端只需发送参数,避免了恶意输入直接构造和执行 SQL 命令。


    3. 校验和过滤(传统防护方法)

    在某些情况下,预编译可能无法适用或配置复杂,传统防护方法仍然具有重要作用。

    3.1 输入校验

    • 数据类型检查:确保输入数据类型与业务逻辑一致。例如:

      $id = isset($_GET['id']) ? $_GET['id'] : 1;if (!is_int($id)) {    die('非法的数据类型');}
    • 数据范围验证:检查输入数据是否在合理范围内。例如:

      if ($id <= 0) {    die('输入超出范围');}
    • SQL 拼接校验:拼接 SQL 时,进行语法检查。

    3.2 特殊字符过滤

    使用 preg_replace 或类似的工具过滤 SQL 特殊字符。例如:

    function removeSpecialChar($param) {    return preg_replace(['~"]'). machAll($param);}$name = removeSpecialChar($_GET['name']);

    避免 piercing SQL injection。

    3.3 禁用魔术引号

    PHP 提供的魔术引号选项 (magic_quotes_gpc) 不建议开启,因为 RSnake 等工具已有绕过方法。


    4. 宽字节注入防护

    使用 mysql_real_escape_string 进行输入的宽字节字符转义,数据库需先设置字符集为 GBK 或 Binary:

    mysql_query('SET NAMES "gbk"'); kde Wei;ID 3: protect against multibyte注入。
    上一篇:什么是计算机???
    下一篇:第一代电脑

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年04月25日 16时01分29秒