首页 后端开发 php教程 谈谈PHP弱类型安全问题

谈谈PHP弱类型安全问题

Apr 27, 2019 am 11:37 AM
php 弱类型

本篇文章小编想和大家谈谈PHP弱类型,PHP弱类型给程序员书写代码带来了很大的便利,但是任何事物都有两面性,现在随着小编一起了解一下吧。

0x00 弱类型初探

没有人质疑php的简单强大,它提供了很多特性供开发者使用,其中一个就是弱类型机制。

在弱类型机制下 你能够执行这样的操作

<?php
$var = 1;
$var = array();
$var = "string";
?>
登录后复制

php不会严格检验传入的变量类型,也可以将变量自由的转换类型。

比如 在$a == $b的比较中

$a = null; $b = false; //为真
$a = &#39;&#39;; $b = 0; //同样为真
登录后复制

然而,php内核的开发者原本是想让程序员借由这种不需要声明的体系,更加高效的开发,所以在 几乎所有内置函数以及基本结构 中使用了很多松散的比较和转换,防止程序中的变量因为程序员的不规范而频繁的报错,然而这却带来了安全问题。

0x02 知识预备 php内核之zval结构

在PHP中声明的变量,在ZE中都是用结构体zval来保存的

zval的定义在zend/zend.h

typedef struct _zval_struct zval;  
struct _zval_struct {  
  /* Variable information */  
  zvalue_value value; /* value */  
  zend_uint refcount__gc;  
  zend_uchar type;/* active type */  
  zend_uchar is_ref__gc;  
};  
typedef union _zvalue_value {  
  long lval;  /* long value */  
  double dval;/* double value */  
  struct {  
    char *val;  
    int len;  
  } str;  
  HashTable *ht;  /* hash table value */  
  zend_object_value obj;  
} zvalue_value;
登录后复制

其中php通过type判断变量类型 存入value

如上也就是php内核中弱类型的封装,也是我们后面讲的所有东西的原理和基础。

0x03变量的强制转换

通过刚刚的了解,我们知道zval.type决定了存储到zval.value的类型。

当源代码进行一些未限制类型的比较,或数学运算的时候,可能会导致zval.type的改变,同时影响zval.value的内容改变。

当int遇上string

cp.1 数学运算

当php进行一些数学计算的时候

ar_dump(0 == &#39;0&#39;); // true
var_dump(0 == &#39;abcdefg&#39;); // true  
var_dump(0 === &#39;abcdefg&#39;); // false
var_dump(1 == &#39;1abcdef&#39;); // true
登录后复制

当有一个对比参数是整数的时候,会把另外一个参数强制转换为整数。

相当于对字符串部分

intval再和整数部分比较,其实也就是改变了zval.type的内容 尤为注意的是,'1assd'的转换后的值是1,而‘asdaf’是0

也说明了intval会从第一位不是数字的单位开始进行

所有也有

var_dump(intval(&#39;3389a&#39;));//输出3389
登录后复制

这个例子就告诉我们,永远不要相信下面的代码

if($a>1000){    
mysql_query(&#39;update ... .... set value=$a&#39;)
}
登录后复制

你以为这时候进入该支的万无一失为整数了

其实$a可能是1001/**/union...

cp.2 语句条件的松散判断

举个例子php的switch使用了松散比较. $which会被自动intval变成0如果每个case里面没有break ,就会一直执行到包含,最终执行到我们需要的函数,这里是成功包含

<?php
if (isset($_GET[&#39;which&#39;]))
{
  $which = $_GET[&#39;which&#39;];
  switch ($which)
  {
  case 0:
  case 1:
  case 2:
    require_once $which.&#39;.php&#39;;
    break;
  default:
    echo GWF_HTML::error(&#39;PHP-0817&#39;, &#39;Hacker NoNoNo!&#39;, false);
    break;
  }
登录后复制

cp.3 函数的松散判断

var_dump(in_array("abc", $array));
登录后复制

in_array — 检查数组中是否存在某个值 参数

needle 待搜索的值。

Note: 如果 needle 是字符串,则比较是区分大小写的。 haystack 这个数组。

strict 如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。

可以看到,只有加了strict才会对类型进行严格比较, 那么我们再次把×××和字符串进行比较呢?

var_dump(in_array("abc", $array1));</br>
var_dump(in_array("1bc", $array2));
登录后复制

它遍历了array的每个值,并且作"=="比较(“当设置了strict 用===”)

结果很明显了

如果array1里面有个值为0,那么第一条返回就会为真//intval('abc')=0

如果array2里面有个值为1,那么第二条就会为真//intval('1bc')=1

array_search也是一样的原理

这里的应用就很广泛了,

很多程序员都会检查数组的值,

那么我们完全可以用构造好的int 0或1 骗过检测函数,使它返回为真

总结一下, 在所有php认为是int的地方输入string,都会被强制转换 ,比如

$a = &#39;asdfgh&#39;;//字符串类型的a</br>
echo $a[2];  //根据php的offset 会输出&#39;d&#39;</br>
echo $a[x];  //根据php的预测,这里应该是int型,那么输入string,就会被intval成为0 也就是输出&#39;a&#39;
登录后复制

当数组遇上string

这一个例子我是在德国的一个ctf中遇到,很有意思前面我们讲的都是string和int的比较

那么array碰上int或者是string会有什么化学反应?

由php手册我们知道

Array转换整型int/浮点型float会返回元素个数;

转换bool返回Array中是否有元素;转换成string返回'Array',并抛出warning。

那么实际应用是怎样的呢?

if(!strcmp($c[1],$d) && $c[1]!==$d){
...
}
登录后复制

可以发现,这个分支通过strcmp函数比较要求两者相等且“==”要求两者不相等才能进入。

strcmp() 函数比较两个字符串。

该函数返回:

0 - 如果两个字符串相等

<0 - 如果 string1 小于 string2

>0 - 如果 string1 大于 string2

这里的strcmp函数实际上是将两个变量转换成ascii 然后做数学减法,返回一个int的差值。

也就是说键入'a'和'a'进行比较得到的结果就是0

那么如果让$array和‘a’比较呢?

http://localhost:8888/1.php?a[]=1
var_dump(strcmp($_GET[a],&#39;a&#39;));
登录后复制

这时候php返回了null!

也就是说,我们让这个函数出错从而使它恒真,绕过函数的检查。

0x04时时防备弱类型

作为一个程序员,弱类型确实给程序员书写代码带来了很大的便利,但是也让程序员忘记了$array =array();的习惯。都说一切输入都是有害的

那么其实可以说一切输入的类型也是可疑的,永远不要相信弱类型的php下任何比较函数,任何数学运算。否则,你绝对是被php出卖的那一个。

相关教程:PHP视频教程

以上是谈谈PHP弱类型安全问题的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

CakePHP 使用数据库 CakePHP 使用数据库 Sep 10, 2024 pm 05:25 PM

在 CakePHP 中使用数据库非常容易。本章我们将了解CRUD(创建、读取、更新、删除)操作。

CakePHP 日期和时间 CakePHP 日期和时间 Sep 10, 2024 pm 05:27 PM

为了在 cakephp4 中处理日期和时间,我们将使用可用的 FrozenTime 类。

CakePHP 文件上传 CakePHP 文件上传 Sep 10, 2024 pm 05:27 PM

为了进行文件上传,我们将使用表单助手。这是文件上传的示例。

CakePHP 路由 CakePHP 路由 Sep 10, 2024 pm 05:25 PM

在本章中,我们将学习以下与路由相关的主题?

讨论 CakePHP 讨论 CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP 是 PHP 的开源框架。它的目的是使应用程序的开发、部署和维护变得更加容易。 CakePHP 基于类似 MVC 的架构,功能强大且易于掌握。模型、视图和控制器 gu

CakePHP 创建验证器 CakePHP 创建验证器 Sep 10, 2024 pm 05:26 PM

可以通过在控制器中添加以下两行来创建验证器。

CakePHP 日志记录 CakePHP 日志记录 Sep 10, 2024 pm 05:26 PM

登录 CakePHP 是一项非常简单的任务。您只需使用一项功能即可。您可以记录任何后台进程(如 cronjob)的错误、异常、用户活动、用户采取的操作。在 CakePHP 中记录数据很容易。提供了 log() 函数

See all articles