Summary of PHP weak type safety problems

Some time ago, I did the topic on the network attack and defense platform of Nanjing University of Posts and Telecommunications. After writing a writeup, it is necessary to summarize it. Because the topics are all web-based, and all topics are written in PHP, many topics do not consider traditional vulnerabilities such as SQL injection and XSS, and many of them are problems with the syntax of PHP itself. Given that PHP is currently the best language in the world, problems with PHP itself can also be counted as an aspect of web security. The feature in PHP training is weak typing, and the loose handling of incoming parameters by built-in functions. This article is mainly to record the problems in the functions of PHP that I encountered on the offensive and defensive platform, as well as the problems caused by weak types of PHP.
Introduction to PHP Weak Types
In PHP, the following operations can be performed.
$param = 1;
$param = array();
$param = "stringg";
Weakly typed languages ​​have no restrictions on the data type of variables, you can assign variables to any other type of variable at any time, and the variable It can also be converted to any other type of data.
Type conversion problems
Type conversion is an unavoidable problem. For example, when the parameters of GET or POST need to be converted to int type, or when the two variables do not match, PHP will automatically convert the variables. But PHP is a weakly typed language, which leads to many unexpected problems when performing type conversions.
Comparison operator
Type conversion
In the comparison of $a==$b
$a=null;$b=flase; //true
$a='';$b=null; //true
There are many more examples, this All comparisons are equal.
There are also type conversion problems when using comparison operators, as follows:
0=='0' //true
0 == 'abcdefg' //true
0 === 'abcdefg' //false
1 == '1abcdef' //true
variable exists when variables of different types are compared The problem of conversion, there may be problems after conversion.
Hash comparison
In addition to the above method, there are also problems when performing hash comparison. As follows:
"0e132456789"=="0e7124511451155" //true
"0e123456abc"=="0e1dddada" //false
"0e1abc"=="0" //true
When comparing, if the character 0e\d+ is encountered string, the string will be parsed into scientific notation. So in the above example both numbers have the value 0 and thus are equal. If the pattern of 0e\d+ is not satisfied, it will not be equal. This topic is tested in the md5 collision in the offensive and defensive platform.
Hexadecimal Conversion There is
also a problem when comparing hexadecimal remainder strings. For example:
"0x1e240"=="123456" //true
"0x1e240"==123456 //true
"0x1e240"=="1e240"
//false When one of the strings starts with 0x, PHP will parse the string into decimal and then compare it. When 0×1240 is parsed into decimal, it is 123456, so it is compared with 123456 of int type and string type. equal. The difficulty of naming in the offensive and defensive platform is the characteristic of the investigation.
Type conversion The
common conversion is mainly to convert int to string, and string to int.
int to string:
$var = 5;
mode 1: $item = (string)$var;
mode 2: $item = strval($var);
string to int: intval() function.
For this function, you can look at 2 examples first.
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
indicates that when intval() is converted, it will Begin the conversion until a non-numeric character is encountered. Even if there is a string that cannot be converted, intval() will not report an error but return 0.
This feature of intval() has been tested in the topic of MYSQL in the offensive and defensive platform.
At the same time, programmers should not use the following code when programming:
if(intval($a)>1000) {
    mysql_query("select * from news where id=".$a)
}
At this time, $a's The value may be 1002 union ..... Looseness
of parameters of built-in functions Looseness of
built-in functions means that when a function is called, a parameter type that the function cannot accept is passed to the function. The explanation is a bit awkward, or the problem is explained directly through practical examples. The following will focus on a few such functions.
md5()
$array1[] = array(
    "foo" => "bar",
    "bar" => "foo",
);
$array2 = array("foo", "bar", "hello", "world" );
var_dump(md5($array1)==var_dump($array2)); //true
The description of the md5() function in the PHP manual is string md5 ( string $str [, bool $raw_output = false ] ), md5( ) needs to be a parameter of type string. But when you pass an array, md5() will not report an error, and the knowledge will not be able to correctly calculate the md5 value of the array, which will cause the md5 value of any two arrays to be equal. The feature of this md5() is also tested in the bypass again in the offensive and defensive platform.
strcmp()
The description of the strcmp() function in the official PHP manual is int strcmp ( string $str1 , string $str2 ), and you need to pass 2 string type parameters to strcmp(). If str1 is less than str2, return -1, if equal, return 0, otherwise return 1. The essence of the strcmp function to compare strings is to convert two variables into ascii, then perform a subtraction operation, and then determine the return value according to the operation result.
What if the argument passed to strcmp() is a number?
$array=[1,2,3];

This feature of strcmp has been tested in the pass check in the offensive and defensive platform.
switch()
If switch is a case judgment of a number type, switch will convert the parameter to int type. As follows:
$i = "2abc";
switch ($i) {
case 0:
case 1:
case 2:
    echo "i is less than 3 but not negative";
    break;
case 3:
    echo "i is 3";
}
this When the program outputs i is less than 3 but not negative, it is because the switch() function converts the type of $i, and the conversion result is 2.
in_array()
In the PHP manual, the explanation of the in_array() function is bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ), if the strict parameter is not provided, then in_array will use loose comparison to determine Whether $needle is in $haystack. When the value of stringe is true, in_array() will compare whether the type of needls is the same as the type in haystack.
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array));
var_dump(in_array('1bc', $array)); //true
You can see that the above cases return true, because 'abc' will be converted to 0, and '1bc' will be converted to 1.
array_search() and in_array() have the same problem.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326655937&siteId=291194637