• PHP安全之道学习笔记2:编码安全指南


    编码安全指南

    编程本身就应该是一门艺术,而安全编程更是一种在刀尖上舞蹈的艺术,不仅要小心脚下的锋利寒刃,更要小心来自网络黑客或攻击者的狂轰乱炸。
    - by code artist

    • 1.hash比较的缺陷
      经过试验发现,当Hash值以"0e"开头且后面都为数字,当和数字进行比较的时候总会被判断和0相等

    例如:

    var_dump('0e1327544' == 0); // bool(true)

    当密码被md5计算后,可能会以"0e"开头,下面这个例子可以绕过密码验证。
    经过我的验证PHP 7.1.x后没有这种问题。

    <?php
        $password_from_db = "0e23434";
        $password = "2323"; // 随意的一个密码。来自$_POST,即表单提交
        if ($password_from_db == md5($password)) {
            echo "login success!";
        } else {
            echo "login fails";
        }
    

    更安全的hash比较:
    可以使用内置函数hash_equals()来比较hash值。(PHP版本必须是5.6及其以上)

     if (hash_equals($password_from_db, md5($password)) {
         .....// other logic
     }
    
    
    • 2.bool比较的缺陷

    json_decode和unserialize函数可能将部分结构解析成bool值,造成一些比较上的缺陷。

    先举例json_decode的案例:

    <?php
    $str = '{"user":true, "pass": true}';
    
    $data = json_decode($str, true);
    
    if ($data['user'] == 'root' && $data['pass'] == 'pass') {
        echo "login success
    ";
    } else {
        echo "login fails
    ";
    }
    

    执行结果为:login success
    这样利用bool比较的漏洞就绕过了登录或者授权验证。

    unserialize过程相逆,结果类似,也会出现安全问题。

    正确的做法还是使用"==="来进行比较,这不光是php,包括一些其他脚本语言或者静态语言,都请严谨地使用全等于符号进行比较。

    • 3.数值比较

    PHP虽然是弱类型语言,但是数据类型也有数值范围。对于整型而言,最大值为PHP_INT_MAX(即9223372036854775807)
    攻击者可以利用最大值越界,绕过一些验证,如登录、账号充值等等。

    举例:

    $a = 9223372036854775807;
    $b = 9223372036854775827;
    var_dump($a === $b); // bool(true)
    var_dump($a % 100); // int(0)
    

    由此,可见全等号(===)也不是万能的,具体场景下要更小心。经验证,PHP7.1.x后不会出现该问题,5.x的可能出现。

    在实际业务逻辑里面一定要注意判断最大值问题,避免越界带来的问题。

    当使用超长浮点数变量的时候,PHP也会出错。

    <?php
    $uid = 0.999999999999999999;
    if ($uid == "1") {
        echo "search uid is 1 for data
    "; // 这里PHP将$uid约等于1了,进入该判断条件里的逻辑
    }
    

    同理,2.999999999999也会被当成3,这就是超越浮点数精度造成的偏差。

    解决办法有很多,最简单的就是用is_int()函数进行判断,如果不是整型,则报错或做错误处理。

    • 4.switch缺陷

    当用case判断数字的时候,switch会把参数转换成int类型进行计算,代码如下:

    <?php
    $num = "1FreePHP";
    switch ($num) {
        case 0: echo "nothing";
            break;
        case 1: echo "1 hacker here!";
            break;
        case 2: echo "2 hackers here";
            break;
        default:
            echo "confused";
    }
    
    

    最后输出:1 hacker here!

    所以,请使用is_numeric()函数进行判断,保证数据类型如预期的一致。

    • 5.数组缺陷。
      in_array()和array_search()函数在没有使用严格模式的情况下会用松散比较,可能造成一些错误。
      例如:
    <?php
    $arr = [0, 2, 3, "4"];
    var_dump(in_array('freephp', $arr)); // true
    var_dump(array_search('freephp', $arr)); // 0: 下标
    var_dump(in_array('2freephp', $arr)); // true
    var_dump(array_search('3freephp', $arr)); // 2: 下标
    
    

    总的来说,PHP工程师对于这种弱类型语言的使用上要更加小心,虽然平时写起业务来“短平快”,但安全编程也不要忘记,能用上hint的高版本PHP就进行标注清楚入参、出参,让PHP代码更加健壮。

  • 相关阅读:
    python导入requests库一直报错原因总结 (文件名与库名冲突)
    Windows下,python pip安装时ReadTimeoutError解决办法
    win10家庭版怎么开启Administrator超级管理员帐户
    关于Centos7 firewalld防火墙开放端口后仍不能访问ftp和nginx的问题解决
    Nginx下配置ThinkPhp多入口访问
    phpStudy配置站点 解决You don't have permission to access / on this server
    非微信内置浏览器中的网页调起微信支付的方案研究
    两种解决方法 PHP Warning: File upload error
    chrome浏览器的跨域设置——包括版本49前后两种设置
    ESA2GJK1DH1K基础篇: 阿里云物联网平台: 阿里云物联网平台加入规则引擎(云产品流转),让两个MQTT设备之间实现通信
  • 原文地址:https://www.cnblogs.com/freephp/p/11945206.html
Copyright © 2020-2023  润新知