• PHP安全之道3:常见漏洞和攻防


    第一篇 SQL注入

    安全配置和编程安全并不是万全之法,攻击者往往可以通过对漏洞的试探找到新的突破口,甚至0days。

    下面总结以下常见漏洞,在日常开发维护工作中可以留意。

    *聊聊老朋友:SQL注入漏洞

    多年前我还在念本科三年级的时候就做了一次关于SQL注入的攻防实验,SQL注入在WEB1.0时代是非常常见的攻击手段,特别是一些远古时期的ASP、PHP站点,往往容易被注入提权。

    简单来说SQL注入就是利用url中参数请求,不断尝试获取数据库信息,从猜字段,推测表,甚至到最后暴库得到后台管理员账号密码。

    常见类型

    A.报错注入
    假设可以通过url来传递该参数,如:
    https://learnhackerphp.com/search?username=freephp
    如本来的sql为:

    select * from users where name = 'freephp'

    但是我们在浏览器浏览框中输入:

    https://learnhackerphp.com/search?username=freephp'lol

    则sql语句变为:

    select * from users where name='frephp'lol'

    这会导致sql语句执行报错,如果我们开启了错误调试,可能会把数据库的错误堆栈打印到浏览器页面,这会被别有用心之辈利用。网站上线后一定设置display_errors=Off。

    B.普通注入

    例子如下:

    https://localhost/search.php?name=name' OR 'a'='a

    最终SQL为:
    select * from user whre name=' name' OR 'a' ='a'

    这变成了一个万能查询语句,可以查到你任何想要的数据,利用union和复合语句,甚至可以获取到数据库任何数据。

    C.隐式类型注入

    先了解一下MySQL默认的查询优化器对入参的处理:

    输入类型 表字段类型 转换后的类型
    NULL 任意类型 NULL
    STRING STRING STRING
    INT INT INT
    INT STRING DOUBLE
    INT DOUBLE DOUBLE
    INT TIMESTAMP TIMESTAMP
    任意类型 DECIMAL DECIMAL
    任意类型 十六进制 二进制

    编写如下sql:

    select * from user whre address=0

    可以获取到该表的所有数据

    D.无套路方式试探

    比如在SQL语句当中附加一些其他执行命令,如:

    select * from user where if (MID(version(), 1, 1) LIKE 5, sleep(5), 1)

    如果真的让MySQL查询sleep了5秒,说明MySQL版本为5.

    讲完了常见SQL注入,那么如何来防范呢。其实PHP已经提供了一些优秀的预处理。

    可以使用PDO或者mysqli*系列函数,对sql语句进行预编译,杜绝sql注入。

    <?php
    require_once('../conf/db.php');
    $pdo = new PDO($dns, $user, $password);
    // ... some logic codes
    
    $sql = 'insert into user (name,address) values(:name,:address)';
    $stmt = $pdo->prepare($sql);
    
    $name = "freephp'hack";
    $address= "CDC,china";
    
    // 绑定参数
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':address', $address);
    
    $stmt->execute();
    
    if ($stmt->errorCode() == 0) {
        echo "insert success";
    } else {
        print_r($stmt->errorInfo());
    }
    

    然而在默认情况下,使用PDO也不是让MySQL执行真正的预处理语句,一定要添加如下代码:

    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO:ERRMODE_EXCEPTION);
    
    

    另外我们也应该对于用户的入参进行判断,比如有效性判断、类型判断,甚至加入一些有效类型数组来约束。

    不要相信任何来自用户的数据,永远都留有一个悲观锁,即使你是一个命中注定的乐天派。

  • 相关阅读:
    jquery-ui Sortable拖拽排序,刷新后保持排序后的位置
    JQ动态获取URL参数
    JQ简单点赞功能
    Netty源码分析 (九)----- 拆包器的奥秘
    Netty源码分析 (八)----- write过程 源码分析
    Netty源码分析 (七)----- read过程 源码分析
    Netty源码分析 (六)----- 客户端接入accept过程
    Netty源码分析 (五)----- 数据如何在 pipeline 中流动
    Netty源码分析 (四)----- ChannelPipeline
    Netty源码分析 (三)----- 服务端启动源码分析
  • 原文地址:https://www.cnblogs.com/freephp/p/12001901.html
Copyright © 2020-2023  润新知