>  기사  >  백엔드 개발  >  PHP 약한 유형을 사용할 때 주의해야 할 보안 문제 요약

PHP 약한 유형을 사용할 때 주의해야 할 보안 문제 요약

伊谢尔伦
伊谢尔伦원래의
2017-06-29 13:31:441207검색

약한 유형의 언어는 약한 유형의 정의 언어라고도 합니다. 강력한 형식의 정의와 반대입니다. VB, PHP 등의 언어는 Weakly Types를 사용하여 PHP의 Weak Types에 대한 보안 문제를 자세히 소개합니다.

머리말

PHP가 세계 최고의 언어라는 것은 누구나 알고 있으며, PHP 자체의 문제도 웹 보안의 한 측면으로 볼 수 있다고 생각합니다. PHP의 특징은 약한 유형과 내장 함수 들어오는 매개변수의 느슨한 처리입니다.

이 글은 주로 공격형 플랫폼과 방어형 플랫폼에서 겪었던 PHP 함수의 문제점과 PHP의 약한 유형으로 인한 문제점을 기록하기 위한 것입니다. PHP를 배우거나 사용할 때 모든 사람이 참조할 수 있는 특정 값이 있습니다. 아래를 살펴보겠습니다.

PHP 약한 타이핑 소개

편집자는 PHP가 개발자가 사용할 수 있는 많은 고유한 기능을 제공하기 때문에 PHP가 매우 강력하다고 생각합니다. 그 중 하나는 php 약한 타이핑 메커니즘입니다.

PHP에서는 다음 작업을 수행할 수 있습니다.

$param = 1;
$param = array();
$param = "stringg";

약한 유형의 언어에는 변수의 데이터 유형에 대한 제한이 없습니다. 언제든지 다른 유형의 변수에 변수를 할당할 수 있으며 변수는 다른 유형의 데이터로 변환될 수도 있습니다.

유형 변환Problems

유형 변환은 피할 수 없는 문제입니다. 예를 들어, GET 또는 POST 매개변수를 int 유형으로 변환해야 하거나 두 변수가 일치하지 않는 경우 PHP는 자동으로 변수를 변환합니다. 그러나 PHP는 약한 유형의 언어이므로 유형 변환을 수행할 때 예상치 못한 많은 문제가 발생합니다.

비교 연산자

유형 변환

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

$a=null;$b=flase ; //true
$a='';$b=null; //true

这样的例子还有很多,这种比较都是相等。

使用比较操作符的时候也存在类型转换的问题,如下:

0=='0' //true
0 == 'abcdefg' //true
0 === 'abcdefg' //false
1 == '1abcdef' //true

当不同类型的变量进行比较的时候就会存在变量转换的问题,在转换之后就有可能会存在问题。

Hash比较

除了以上的这种方式之外在进行hash比较的时候也会存在问题。如下:

"0e132456789"=="0e7124511451155" //true
"0e123456abc"=="0e1dddada" //false
"0e1abc"=="0"  //true

在进行比较运算时,如果遇到了0ed+这种字符串,就会将这种字符串解析为科学计数法。所以上面例子中2个数的值都是0因而就相等了。如果不满足0ed+这种模式就不会相等。这个题目在攻防平台中的md5 collision就有考到。

十六进制转换

还存在一种十六进制余字符串进行比较运算时的问题。

例子如下:

"0x1e240"=="123456" //true
"0x1e240"==123456 //true
"0x1e240"=="1e240" //false

当其中的一个字符串是0x开头的时候,PHP会将此字符串解析成为十进制然后再进行比较,0x1240解析成为十进制就是123456,所以与int类型和string类型的123456比较都是相等。攻防平台中的起名字真难就是考察的这个特性。

类型转换

常见的转换主要就是int转换为string,string转换为int。

int转string:

$var = 5;
方式1:$item = (string)$var;
方式2:$item = strval($var);

string转intintval()函数。

对于这个函数,可以先看2个例子。

var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0

说明intval()转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。即使出现无法转换的字符串,intval()不会报错而是返回0。

intval()的这种特性在攻防平台中的MYSQL这道题目中就有考到。

同时,程序员在编程的时候也不应该使用如下的这段代码:

if(intval($a)>1000) {
 mysql_query("select * from news where id=".$a)
}

这个时候$a的值有可能是1002 union…..

内置函数的参数的松散性

内置函数的松散性说的是,调用函数时给函数传递函数无法接受的参数类型。解释起来有点拗口,还是直接通过实际的例子来说明问题,下面会重点介绍几个这种函数。

md5()

$array1[] = array(
 "foo" => "bar",
 "bar" => "foo",
);
$array2 = array("foo", "bar", "hello", "world");
var_dump(md5($array1)==var_dump($array2)); //true

PHP手册中的md5()函数的描述是string md5 ( string $str [, bool $raw_output = false ] ) md5()中的需要是一个string类型的参数。但是当你传递一个array时,md5()不会报错,知识会无法正确地求出array的md5值,这样就会导致任意2个array的md5值都会相等。这个md5()

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

의 비교에는 이런 예가 많이 있는데, 이 비교는 모두 동일합니다.

비교 연산자를 사용할 때 다음과 같은 유형 변환 문제도 있습니다.

$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";
}

다른 유형의 변수를 비교할 때 변수 변환 문제가 발생하며 변환 후 문제가 발생할 수 있습니다. 🎜🎜🎜해시 비교🎜🎜🎜위의 방법 외에도 해시 비교를 수행할 때에도 문제가 있습니다. 🎜
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true
🎜비교 연산을 수행할 때 0ed+와 같은 문자열이 발견되면 이 문자열을 과학적 표기법으로 파싱합니다. 따라서 위 예에서 두 숫자의 값은 모두 0이므로 동일합니다. 0ed+가 만족되지 않으면 이 패턴은 동일하지 않습니다. 이 질문은 공격 및 방어 플랫폼의 md5 충돌에서 테스트되었습니다. 🎜🎜🎜16진수16진수 변환🎜🎜🎜🎜16진수 나머지 문자열도 있습니다. 비교 연산에 문제가 있습니다. 🎜🎜예제는 다음과 같습니다. 🎜rrreee🎜문자열 중 하나가 0x로 시작하면 PHP는 문자열을 십진수로 구문 분석한 후 비교합니다. 십진수로 구문 분석한 0x1240은 123456이므로 int 유형 및 문자열의 123456과 같습니다. 유형. 모든 비교가 동일합니다. 공격 및 방어 플랫폼에서 이름을 지정하기 어려운 것은 이러한 검사 특성 때문입니다. 🎜🎜🎜🎜유형 변환🎜🎜🎜🎜일반적인 변환은 주로 int를 문자열로, 문자열을 int로 변환하는 것입니다.
🎜🎜🎜int를 문자열로: 🎜🎜rrreee🎜🎜문자열을 int🎜로: intval() 함수.
🎜🎜이 기능에 대해 먼저 2가지 예를 살펴보세요. 🎜rrreee🎜설명: intval()을 변환할 때 숫자가 아닌 문자를 만날 때까지 문자열의 시작 부분부터 변환합니다. 변환할 수 없는 문자열이 나타나도 intval()은 오류를 보고하지 않고 0을 반환합니다.
🎜🎜intval() 이 기능은 공격 및 방어 플랫폼의 MYSQL 문제에서 테스트되었습니다.
🎜🎜동시에 프로그래머는 프로그래밍할 때 다음 코드를 사용해서는 안 됩니다. 🎜rrreee🎜 이때 $a의 값은 1002 Union이 될 수 있습니다...🎜🎜🎜🎜내장
함수 매개변수의 느슨함🎜🎜🎜🎜🎜내장 함수의 느슨함은 함수를 호출할 때 함수가 허용되지 않는 매개변수 유형 함수에 전달됩니다. 설명이 다소 혼란스럽기 때문에 실제 예제를 통해 문제를 직접 설명하겠습니다. 아래에서는 이러한 몇 가지 기능에 중점을 둘 것입니다. 🎜🎜🎜md5()🎜🎜rrreee🎜PHP 매뉴얼의 md5() 함수 설명은 string md5 ( string $str [, bool $raw_output = false ] ) , md5 () 의 요구 사항은 문자열 유형 매개변수입니다. 그러나 배열을 전달하면 md5()는 오류를 보고하지 않으며 지식은 배열의 md5 값을 올바르게 계산할 수 없게 됩니다. 이로 인해 두 가지의 md5 값이 발생하게 됩니다. 배열이 같아야 합니다. md5()의 이 기능은 공격 및 방어 플랫폼에서도 다시 우회로 고려됩니다. 🎜🎜🎜strcmp()🎜🎜

strcmp()函数在PHP官方手册中的描述是int strcmp ( string $str1 , string $str2 ) ,需要给strcmp()传递2个string类型的参数。如果str1小于str2,返回-1,相等返回0,否则返回1。strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。

如果传入给出strcmp()的参数是数字呢?

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

strcmp这种特性在攻防平台中的pass check有考到。

switch()

如果switch是数字类型的case的判断时,switch会将其中的参数转换为int类型。如下:

$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";
}

这个时候程序输出的是i is less than 3 but not negative,是由于switch()函数将$i进行了类型转换,转换结果为2。

in_array()

在PHP手册中,in_array()函数的解释是bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) ,如果strict参数没有提供,那么in_array就会使用松散比较来判断$needle是否在$haystack中。当strince的值为true时,in_array()会比较needls的类型和haystack中的类型是否相同。

$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true

可以看到上面的情况返回的都是true,因为'abc'会转换为0,'1bc'转换为1。

<a href="http://www.php.cn/wiki/1007.html" target="_blank">array_search</a>()in_array()也是一样的问题。

위 내용은 PHP 약한 유형을 사용할 때 주의해야 할 보안 문제 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.