PHP Conference Japan 2024

空字节相关问题

由于PHP 使用底层的 C 函数进行文件系统相关操作,因此它可能以一种相当出乎意料的方式处理空字节。由于空字节在 C 中表示字符串的结尾,因此包含空字节的字符串不会被完全考虑,而只会被考虑直到出现空字节为止。以下示例显示了一个演示此问题的易受攻击的代码

示例 #1 易受空字节攻击的脚本

<?php

$file
= $_GET['file']; // "../../etc/passwd\0"

if (file_exists('/home/wwwrun/' . $file . '.php')) {
// file_exists 将返回 true,因为文件 /home/wwwrun/../../etc/passwd 存在
include '/home/wwwrun/' . $file . '.php';

// 将包含文件 /etc/passwd
}

?>

因此,在文件系统操作中使用的任何受污染的字符串都应始终正确验证。以下是前面示例的改进版本

示例 #2 正确验证输入

<?php

$file
= $_GET['file'];

// 将允许的值列入白名单
switch ($file) {
case
'main':
case
'foo':
case
'bar':
include
'/home/wwwrun/include/' . $file . '.php';
break;
default:
include
'/home/wwwrun/include/main.php';
}

?>
添加备注

用户贡献的备注 2 条备注

13
匿名
10 年前
看起来这个问题在 PHP 5.3 中已修复 https://bugs.php.net/bug.php?id=39863
1
cornernote [at] gmail.com
9 年前
清除空字节输入

<?php
$clean
= str_replace(chr(0), '', $input);
?>
To Top