Нулевые байты и безопасность

Поскольку для работы с файловой системой PHP внутренне вызывает функции языка C, он иногда обрабатывает нулевые байты неожиданным образом. Поскольку в C нулевые байты обозначают конец строки, PHP не принимает всю строку с NUL-байтом, а только до позиции перед нулевым байтом. Следующий пример содержит уязвимый код, который показывает проблему:

Пример #1 Пример уязвимого скрипта с NUL-байтом

<?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';

// 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 notes

up
13
Anonymous
10 years ago
Looks like this issue was fixed in PHP 5.3 https://bugs.php.net/bug.php?id=39863
up
1
cornernote [at] gmail.com
9 years ago
clean input of null bytes:

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