由于 PHP 的文件系统操作是基于 C 语言的函数的,所以它可能会以您意想不到的方式处理 Null 字符。 Null字符在 C 语言中用于标识字符串结束,一个完整的字符串是从其开头到遇见 Null 字符为止。
借用官方手册中的一个例子:
$file = $_GET['file']; // "../../etc/passwd\0" if (file_exists('/home/wwwrun/'.$file.'.php')) { // file_exists will return true as the file /home/wwwrun/../../etc/passwd exists include '/home/wwwrun/'.$file.'.php'; // the file /etc/passwd will be included }
以上代码在PHP5.3以前版本中,文件/etc/passwd将会被加载。对以后的版本没有影响。
虽然这个遇到\0会把字符截断的问题已经被修复了,但是在PHP中文件系统相关函数中还是有一点影响的,比如file_exists(),is_file()等。
如下代码:
$filename = "/etc/passwd\0"; $res = file_exists($filename); var_dump($res);
以上代码的执行结果如下:
Warning: file_exists() expects parameter 1 to be a valid path, string given in /usr/local/var/www/a.php on line 3
/usr/local/var/www/a.php:4:null
解决办法
对null字符进行替换
$input = str_replace(chr(0), '', $input);