搜索
首页后端开发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 - 如果两个字符串相等

a6b9cc46ad9ec641b86c82c8b1b411f80 - 如果 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中文网其他相关文章!

声明
本文转载于:51cto。如有侵权,请联系admin@php.cn删除
绝对会话超时有什么区别?绝对会话超时有什么区别?May 03, 2025 am 12:21 AM

绝对会话超时从会话创建时开始计时,闲置会话超时则从用户无操作时开始计时。绝对会话超时适用于需要严格控制会话生命周期的场景,如金融应用;闲置会话超时适合希望用户长时间保持会话活跃的应用,如社交媒体。

如果会话在服务器上不起作用,您将采取什么步骤?如果会话在服务器上不起作用,您将采取什么步骤?May 03, 2025 am 12:19 AM

服务器会话失效可以通过以下步骤解决:1.检查服务器配置,确保会话设置正确。2.验证客户端cookies,确认浏览器支持并正确发送。3.检查会话存储服务,如Redis,确保其正常运行。4.审查应用代码,确保会话逻辑正确。通过这些步骤,可以有效诊断和修复会话问题,提升用户体验。

session_start()函数的意义是什么?session_start()函数的意义是什么?May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

为会话cookie设置httponly标志的重要性是什么?为会话cookie设置httponly标志的重要性是什么?May 03, 2025 am 12:10 AM

设置httponly标志对会话cookie至关重要,因为它能有效防止XSS攻击,保护用户会话信息。具体来说,1)httponly标志阻止JavaScript访问cookie,2)在PHP和Flask中可以通过setcookie和make_response设置该标志,3)尽管不能防范所有攻击,但应作为整体安全策略的一部分。

PHP会议在网络开发中解决了什么问题?PHP会议在网络开发中解决了什么问题?May 03, 2025 am 12:02 AM

phpsessions solvathepromblymaintainingStateAcrossMultipleHttpRequestsbyStoringDataTaNthEserVerAndAssociatingItwithaIniquesestionId.1)他们储存了AtoredAtaserver side,通常是Infilesordatabases,InseasessessionIdStoreDistordStoredStoredStoredStoredStoredStoredStoreDoreToreTeReTrestaa.2)

可以在PHP会话中存储哪些数据?可以在PHP会话中存储哪些数据?May 02, 2025 am 12:17 AM

phpsessionscanStorestrings,数字,数组和原始物。

您如何开始PHP会话?您如何开始PHP会话?May 02, 2025 am 12:16 AM

tostartaphpsession,usesesses_start()attheScript'Sbeginning.1)placeitbeforeanyOutputtosetThesessionCookie.2)useSessionsforuserDatalikeloginstatusorshoppingcarts.3)regenerateSessiveIdStopreventFentfixationAttacks.s.4)考虑使用AttActAcks.s.s.4)

什么是会话再生,如何提高安全性?什么是会话再生,如何提高安全性?May 02, 2025 am 12:15 AM

会话再生是指在用户进行敏感操作时生成新会话ID并使旧ID失效,以防会话固定攻击。实现步骤包括:1.检测敏感操作,2.生成新会话ID,3.销毁旧会话ID,4.更新用户端会话信息。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),