php比較オペレータのセキュリティ問題を詳しく解く

4821 ワード

phpの比較オペレータには==(等しい)緩和比較,==(完全に等しい)厳格な比較があり,興味深い問題が多く導入される.
ばらばらに比較するとphpは文字から数字、非boolタイプからboolタイプに統一され、予想外の実行効果を避けるために厳密な比較を使用する必要があります.php manualの比較演算子テーブルは次のとおりです.

               
$a == $b       TRUE,        $a    $b。
$a === $b       TRUE,   $a    $b,          。
$a != $b       TRUE,        $a     $b。
$a <> $b       TRUE,        $a     $b。
$a !== $b        TRUE,   $a     $b,         。
$a < $b        TRUE,   $a      $b。
$a > $b        TRUE,   $a      $b。
$a <= $b         TRUE,   $a        $b。
$a >= $b         TRUE,   $a        $b。

0 x 01セキュリティの問題
1 hash比較欠陥
phpはhash文字列を処理するときに使います!=,==hash比較を行い、hash値が0 eで始まると、後ろが数字で、さらに数字と比較すると、0*10^nか0かと解釈され、等しいと判断され、登録を迂回します.
root@kali:~/tool# php -r 'var_dump("00e0345"== "0");var_dump("0e123456789"=="0");var_dump("0e1234abc"=="0");' bool(true) bool(true) bool(false)
0 e 12345678が0*10^12345678と解釈されるように、緩やかな比較は尽力モードを実行し、eがすべて数字ではない場合を除いては等しくなく、var_dump("0 e 1234 abc"="0")が見えます.
2 bool欺瞞
json_が存在する場合decodeやunserializeの場合、一部の構造はboolタイプと解釈され、詐欺にもなります.json_decodeサンプルコード:

$json_str = '{"user":true,"pass":true}';
$data = json_decode($json_str,true);
if ($data['user'] == 'admin' && $data['pass']=='secirity')
{
  print_r('logined in as bool'."
"); }

実行結果:
root@kali:/var/www# php/root/php/hash.php logined in as bool
unserializeサンプルコード:

$unserialize_str = 'a:2:{s:4:"user";b:1;s:4:"pass";b:1;}';
$data_unserialize = unserialize($unserialize_str);
if ($data_unserialize['user'] == 'admin' && $data_unserialize['pass']=='secirity')
{
  print_r('logined in unserialize'."
"); }

実行結果は次のとおりです.
root@kali:/var/www# php/root/php/hash.php logined in unserialize
3デジタル変換詐欺

$user_id = ($_POST['user_id']);
if ($user_id == "1")
{
  $user_id = (int)($user_id);
  #$user_id = intval($user_id);
  $qry = "SELECT * FROM `users` WHERE user_id='$user_id';";
}
$result = mysql_query($qry) or die('
' . mysql_error() . '
' );
print_r(mysql_fetch_row($result));
user_をid=0.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
Array (     [0] => 0     [1] => lxx'     [2] =>     [3] =>     [4] =>     [5] => )
はuserをクエリーするのですがidのデータはuser_id=0のデータ.intとintvalは を するときに く、 のコードがあります.

if ($_POST['uid'] != 1) {
 $res = $db->query("SELECT * FROM user WHERE uid=%d", (int)$_POST['uid']);
 mail(...);
} else {
 die("Cannot reset password of admin");
}

1.1に されると、$_を します.POST['uid']!=1の でuid=1のユーザを できるようになった.またintvalには、 に するまですべての を する モードがあります.

if (intval($qq) === '123456')
{
  $db->query("select * from user where qq = $qq")
}

は123456 union select version()に わって する.
4 PHP5.4.4 な
このバージョンのphpの により、2つの がオーバーフローし、 しい
$ php -r 'var_dump("61529519452809720693702583126814"== "61529519452809720000000000000000");' bool(true)
3 :
に の があるのはphp strcmp で、manualではint strcmp(string$str 1、string$str 2)、str 1は の で、str 2は2 の で、str 1がstr 2より さい は<0を し、str 1>str 2であれば>0を し、 は しく0を し、str 2がarrayであれば?

$_GET['key'] = array();
$key = "llocdpocuzion5dcp2bindhspiccy";
$flag = strcmp($key, $_GET['key']);
if ($flag == 0) {
  print "Welcome!";
} else {
  print "Bad key!";
}

:
root@kali:~/php# php strcmp.php PHP Warning:  strcmp() expects parameter 2 to be string, array given in/root/php/strcmp.php on line 13 Welcome!
のタイプの
オペランド1タイプ
オペランド1タイプ

nullまたはstring
string
NULLを「」に し、 または の を います.
boolまたはnull
その のタイプ
boolに 、FALSEobject
object
クラスは の を することができて、 では することができなくて、 じクラスと は じ で (PHP 4の で)を して、PHP 5はそれ の があります
string,resourceまたはnumber
string,resourceまたはnumber
とリソースを に し、 の で
array
array
ないメンバーを つ は さく、 1のキーが 2に しない は できません.そうしないと、 ごとに されます( の を ).
array
その のタイプ
arrayはいつももっと きい
object
その のタイプ
objectは に きい