谈谈PHP弱类型安全问题-php教程

资源魔 34 0
本篇文章小编想以及各人谈谈PHP弱类型,PHP弱类型给顺序员书写代码带来了很年夜的便当,然而任何事物都有两面性,如今跟着小编一同理解一下吧。

0x00 弱类型初探

不人质疑php的简略弱小,它提供了不少特点供开发者应用,此中一个就是弱类型机制。

正在弱类型机制下 你可以执行这样的操作

<?php
$var = 1;
$var = array();
$var = "string";
?>

php没有会严格测验传入的变量类型,也能够将变量自在的转换类型。

比方 正在$a == $b的比拟中

$a = null; $b = false; //为真
$a = ''; $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 == '0'); // true
var_dump(0 == 'abcdefg'); // true  
var_dump(0 === 'abcdefg'); // false
var_dump(1 == '1abcdef'); // true

当有一个比照参数是整数的时分,会把另一个参数强迫转换为整数。

相称于对字符串局部

intval再以及整数局部比拟,其实也就是扭转了zval.type的内容 尤其留意的是,'1assd'的转换后的值是1,而‘asdaf’是0

也阐明了intval会从第一名没有是数字的单元开端进行

一切也有

var_dump(intval('3389a'));//输入3389

这个例子就通知咱们,永远没有要置信上面的代码

if($a>1000){    
mysql_query('update ... .... set value=$a')
}

你认为这时候候进入该支的十拿九稳为整数了

其实$a多是1001/**/union...

cp.2 语句前提的紧凑判别

举个例子php的switch应用了紧凑比拟. $which会被主动intval变为0假如每一个case外面不break ,就会不断执行到蕴含,终极执行到咱们需求的函数,这里是胜利蕴含

<?php
if (isset($_GET['which']))
{
  $which = $_GET['which'];
  switch ($which)
  {
  case 0:
  case 1:
  case 2:
    require_once $which.'.php';
    break;
  default:
    echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', 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 = 'asdfgh';//字符串类型的a</br>
echo $a[2];  //依据php的offset 会输入'd'</br>
echo $a[x];  //依据php的预测,这里应该是int型,那末输出string,就会被intval成为0 也就是输入'a'

当数组赶上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以及&lsquo;a’比拟呢?

http://localhost:8888/1.php?a[]=1
var_dump(strcmp($_GET[a],'a'));

这时候候php前往了null!

也就是说,咱们让这个函数犯错从而使它恒真,绕过函数的反省。

0x04不时防范弱类型

作为一个顺序员,弱类型的确给顺序员书写代码带来了很年夜的便当,然而也让顺序员遗记了$array =array();的习气。都说所有输出都是无害的

那末其实能够说所有输出的类型也是可疑的,永远没有要置信弱类型的php下任何比拟函数,任何数学运算。不然,你相对是被php出卖的那一个。

相干教程:PHP视频教程

以上就是谈谈PHP弱类型平安成绩的具体内容,更多请存眷资源魔其它相干文章!

标签: php php开发教程 php开发资料 php开发自学 弱类型

抱歉,评论功能暂时关闭!