zoukankan      html  css  js  c++  java
  • 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代码更加健壮。

  • 相关阅读:
    JS中Text节点总结
    JS中Document节点总结
    HTML5 Geolocation位置信息定位总结
    HTML5form表单的相关知识总结
    HTML5文档的各个组成部分分类
    JS中Node节点总结
    vue.js指令总结
    javascript string对象方法总结
    php 接口文档自动生产方式
    python使用
  • 原文地址:https://www.cnblogs.com/freephp/p/11945206.html
Copyright © 2011-2022 走看看