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\r\n";
} else {
echo "login fails\r\n";
}
执行结果为: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\r\n"; // 这里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代码更加健壮。
原文地址:https://www.cnblogs.com/freephp/p/11945206.html
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- dotnet 多线程禁止同时调用相同的方法 禁止方法重入调用 双检锁的设计
- android实现倒计时功能(开始、暂停、0秒结束)
- 【-Flutter/Dart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await
- android实现条目倒计时功能
- Android实现简单手电筒功能
- k8s安装自动证书签发cert-manager letsencrypt
- Android仿Keep运动休息倒计时圆形控件
- android通过led实现手电筒功能
- Android 7.0 手电筒控制实现
- 【STM32H7】第13章 RL-TCPnet V7.X之创建多个TCP客户端
- Android倒计时的开始与停止 剩余时分秒的展示
- 由LFI引起的Zimbra邮件管理系统0day
- Android手电筒兼容各个手机与版本
- 【STM32F429】第13章 RL-TCPnet V7.X之创建多个TCP客户端
- RecyclerView仿应用列表实现网格布局