ホームページ  >  記事  >  php教程  >  PHP の弱い型の安全性の問題の概要

PHP の弱い型の安全性の問題の概要

大家讲道理
大家讲道理オリジナル
2016-11-12 11:01:542636ブラウズ

少し前に、南京郵電大学のネットワーク攻撃と防御プラットフォームについて質問しました。記事を書いた後、まだそれを要約する必要があります。問題はすべて Web 形式であり、すべて PHP を使用して作成されているため、SQL インジェクションや XSS などの従来の脆弱性を調査していない問題が多く、その多くは PHP 自体の構文に問題があります。 PHP が現在世界で最高の言語であることを考えると、PHP 自体の問題も Web セキュリティの側面として考慮される可能性があります。 PHP の特徴は、弱い型付けと、組み込み関数による受信パラメータの緩やかな処理です。この記事は主に、攻守のプラットフォームを構築する際に遭遇したPHP関数の問題点や、PHPの弱い型によって引き起こされる問題点を記録するものです。

PHPの弱い型の紹介


PHPでは、次の操作を実行できます。

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

弱い型指定言語では、変数のデータ型に制限がなく、いつでも変数を他の型の変数に割り当てることができ、変数を他の型のデータに変換することもできます。

型変換の問題

型変換は避けられない問題です。たとえば、GET または POST パラメータを int 型に変換する必要がある場合、または 2 つの変数が一致しない場合、PHP は変数を自動的に変換します。ただし、PHP は型指定が弱い言語であるため、型変換を実行するときに多くの予期せぬ問題が発生します。

比較演算子


型変換

$a==$bの比較

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

そのような例はたくさんあり、これらの比較はすべて等しいです。

比較演算子を使用する場合、次のような型変換の問題もあります:

0=='0'//true0 == 'abcdefg'//true0 === 'abcdefg'//false1 == '1abcdef'//true

異なる型の変数を比較する場合、変数の変換の問題が発生し、変換後に問題が発生する可能性があります。

ハッシュ比較

上記の方法に加えて、ハッシュ比較を行う際にも問題があります。次のように:

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

比較演算を実行するときに、0ed+ のような文字列が見つかった場合、この文字列は科学的表記法に解析されます。したがって、上の例の 2 つの数値の値は両方とも 0 であり、等しいです。 0ed+ が満たされない場合、このパターンは等しくなりません。この質問は、攻撃的および防御的なプラットフォームの md5 衝突でテストされます。

16進数変換

16進数の剰余文字列に対して比較演算を実行する場合にも問題があります。例は次のとおりです。

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

文字列の 1 つが 0x で始まる場合、PHP は文字列を 10 進数に解析し、10 進数に解析された 0x1240 は 123456 であるため、int 型の 123456 と同じになります。文字列型。すべての比較は等しい。攻守のプラットフォームで名前を付けるのが難しいのは、捜査の特性によるものです。

型変換

一般的な変換は、主に int から string へ、string から int への変換です。

int から文字列へ:

$var = 5;

方法 1: $item = (string)$var;

方法 2: $item = strval($var);

文字列から int: intval() 関数。

この関数については、まず 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()の要件は文字列型パラメータです。しかし、配列を渡すと、md5() はエラーを報告せず、配列の md5 値を正しく計算できなくなります。これにより、2 つの配列の md5 値が等しくなります。 md5() のこの機能は、攻撃および防御プラットフォームでのバイパスでも考慮されています。

strcmp()

strcmp() 関数は、PHP 公式マニュアルでは int strcmp ( string $str1 , string $str2 ) と記述されており、strcmp() には 2 つの文字列型パラメータを渡す必要があります。 str1 が str2 より小さい場合は -1 が返され、等しい場合は 0 が返され、そうでない場合は 1 が返されます。文字列を比較する strcmp 関数の本質は、2 つの変数を ASCII に変換し、減算演算を実行し、演算結果に基づいて戻り値を決定することです。

strcmp() に渡されるパラメーターが数値の場合はどうなりますか?

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

strcmp この機能は、攻守のプラットフォームのパスチェックでテストされます。

switch()

switchが数値型の場合、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 が 3 未満ですが、負ではありません。これは、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。

array_search()与in_array()也是一样的问题。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。