看起來這個問題已在 PHP 5.3 中修復 https://bugs.php.net/bug.php?id=39863
由於 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';
}
?>