汽车门户网站 源码,室内设计论坛网站,在线免费crm黑白配,企业网站、电子期刊属于企业文化传播载体中的( )。PHP比较漏洞
一, 字符串与数字比较,0e’字符串比较
在 PHP 中处理字符串和数字比较时需要小心谨慎的重要性#xff0c;尤其是在安全敏感的应用中。 在某些情况下#xff0c;PHP 的类型强制转换可能会导致意外和潜在的安全漏洞。
var_dump(admin 0); //true
…PHP比较漏洞
一, 字符串与数字比较,0e’字符串比较
在 PHP 中处理字符串和数字比较时需要小心谨慎的重要性尤其是在安全敏感的应用中。 在某些情况下PHP 的类型强制转换可能会导致意外和潜在的安全漏洞。
var_dump(admin 0); //true
var_dump(1admin 1); //true
var_dump(admin1 1); //false
var_dump(admin1 0); //true
var_dump(0e123456 0e4456789); //true 这段代码展示了 PHP 中的一些有趣且可能导致安全隐患的类型强制转换行为。让我们逐一分析每个表达式
var_dump(admin 0); 在 PHP 中当一个字符串与数字进行比较时如果字符串不是以数字开始则该字符串会被转换为数字 0。因此“admin” 被转换为 0所以 0 0 是 true。
var_dump(1admin 1); 在这个例子中字符串 “1admin” 在尝试转换为数字时会被解析为数字 1因为它以 1 开始忽略后续非数字字符。因此1 1 是 true。
var_dump(admin1 1); 这里 “admin1” 作为字符串不能转换为数字 1因为它不是以数字开始的。它将被转换为 0。所以0 1 是 false。
var_dump(admin1 0); 同上“admin1” 转换为数字时变成了 0所以 0 0 是 true。
var_dump(0e123456 0e4456789); 这是 PHP 类型强制转换中最有趣的一个例子。当一个字符串看起来像是科学记数法时例如 “0e123456”在与另一个类似结构的字符串比较时它们都会被转换为数字 0。
这是因为 e 后面的数字被解释为指数但由于前面的数字是 0所以整个表达式的值为 0。 因此两个看似不同的字符串在这种情况下会被认为是相等的。
二, Hash字符串比较
原理还是科学计数法字符串比较的问题.
测试1:
var_dump(0e123456789012345678901234567890 0); //false
var_dump(0e123456789012345678901234567890 0); //true因为 e 后面的数字被解释为指数但由于前面的数字是 0所以整个表达式的值为 0。
测试2:
$pass $_GET[password];
$password 0e342768416822451524974117254469;if (md5($pass) $password) {echo flag{xx-xx-xxxx-xxx};
}
else {echo error;
}对于上面的代码那么只要是提交的密码的md5值是以0e开头的都会绕过, 比如.
?pwds1885207154a除了使用进行判断外从 PHP 5.6 开始hash_equals() 函数被引入主要用于安全地比较两个字符串的哈希值通常用于密码或敏感数据的验证。
hash_equals() 函数的关键特点
1. 时间恒定的比较
这意味着函数在比较两个字符串时所花费的时间不依赖于字符串的内容。这是预防某些类型的定时攻击的重要特性例如在一些安全关键的应用场景中攻击者可能尝试通过测量不同输入导致的响应时间差异来推断信息。
2. 二进制安全
hash_equals() 安全地处理二进制数据确保在比较过程中不会因为特殊字符如 NULL 字节而意外截断或错误处理。
3. 字符串比较
它专门用于比较字符串而不是用于其他数据类型。
一个典型例子是在用户认证系统中比较用户输入的密码哈希值与存储在数据库中的哈希值
$expected 存储的哈希值;
$provided hash(sha256, 用户输入的密码);if (hash_equals($expected, $provided)) {// 密码匹配
} else {// 密码不匹配
}三, bool比较
1. 在json字符串中:
$str {user:true, pass:true};
$data json_decode($str, true);if($data[user] root $data[pass] myPass){echo 登陆成功 获得flag{xx-ssss-xxxx};
}else{echo 登陆失败;
}这里用户名和pass都是true, 由于使用的是判断, 两个比较的结果都是true.
2. 在序列化字符串中:
$str a:2:{s:4:user;b:1;s:4:pass;b:1;};
$data unserialize($str); if($data[user] root $data[pass] myPass){print_r(获得flag{xx-ssss-xxxx});
}else{print_r(失败);
}a:2: 表示一个数组包含 2 个元素。 s:4:user;b:1; 表示数组的第一个键值对。键是一个长度为 4 的字符串 “user”值是布尔值 true在 PHP 序列化格式中表示为 b:1。 s:4:pass;b:1; 表示数组的第二个键值对。键是一个长度为 4 的字符串 “pass”值也是布尔值 true。 那么用户名和pass都是true, 绕过了判断.
四, 极限值比较
$a98869694308861098395599991222222222222;
$b98869694308861098395599992999999999999;
var_dump($a $b);虽然两个值不同, 但是比较的结果是true.
五, switch比较
PHP 中的 switch 语句是松散比较而不是严格比较。这意味着类型强制转换会发生。
$num 3number;
switch($num){case 0:echo 000;break;case 1:echo 111;break;case 2:echo 222;break;case 3:echo 333;break;default:echo error;
}当 $num 3number; 时由于进行松散比较PHP 会尝试将这个字符串转换为数字。 由于字符串以数字 3 开始其余部分在转换过程中将被忽略因此 $num 被视为数字 3。 结果并不会输出error, 而是333.
六, in_array函数比较
在 PHP 中in_array 和 array_search 函数在默认情况下使用松散比较。 如果没有明确设置 strict 参数为 true这些函数会执行类型强制转换可能导致一些非直观的结果。
$array [a, 0, 1, 2, 3];
var_dump(in_array(abc, $array)); // bool(true)
var_dump(array_search(abc, $array)); // int(1) in_array(abc, $array) 在比较 abc 和数组中的0时由于abc在松散比较中会被视为 0非数字开头的字符串在转换为数字时会成为 0因此 in_array 会返回 true。 同理array_search(abc, $array) 在寻找abc时也会找到0这个元素的位置因此返回 1。