Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую! eurobyte.ru - мощные сервера с Дата-центрами в Нидерландах и Москве. От 159 ₽/мес.

validate_file() │ WP 1.2.0

Проверяет путь к файлу (в том числе относительный) на запрещённые конструкции и соответствие списку разрешённых файлов.

В ядре используется при проверке путей плагинов, выборе шаблонов, редактировании файлов и распаковке архивов.

Используется для предотвращения Directory traversal атак.

Успешная проверка не подтверждает существование файла или права доступа. Функция не проверяет содержимое, расширение и MIME-тип файла.

Будьте внимательны, если проверка пройдена, функция вернет 0, а если не пройдена то вернет число. Поэтому проверять стоит так:

if( validate_file( $file ) === 0 )
	echo 'проверка пройдена';
else
	echo 'проверка не пройдена';

Используйте validate_file_to_edit(), когда нужно проверить путь для редактирования с остановкой выполнения через wp_die() при кодах ошибки 1 и 3. При коде 2 эта обёртка выдаёт null.

Основа для: wp_get_active_and_valid_plugins()
1 раз — 0.000018 сек (очень быстро) | 50000 раз — 0.01 сек (скорость света) | PHP 7.1.2, WP 4.7.5

Хуков нет.

Возвращает

int.

  • 0 - проверка пройдена.
  • 1 - обнаружена запрещённая конструкция с ../.
  • 2 - второй символ нормализованного пути равен :, например в C:/file.php.
  • 3 - путь отсутствует в непустом списке разрешённых файлов.

Проверки ошибок выполняются в порядке 1, 3, 2. При нескольких нарушениях результат соответствует первой сработавшей проверке.

Использование

validate_file( $file, $allowed_files );
$file(строка) (обязательный)

Путь до файла.

Перед проверкой нормализуется через wp_normalize_path(): обратные слеши заменяются прямыми, повторяющиеся слеши сокращаются, кроме двух начальных, а буква диска переводится в верхний регистр.

Код 1 возникает, если после нормализации:

  • Путь равен ../.
  • Подстрока ../ встречается больше одного раза.
  • Единственная подстрока ../ находится не в конце пути.

Пути folder/../, folder/.., .. и абсолютные Unix-пути вроде /etc/passwd сами по себе не отклоняются. Пустая строка и нескалярные значения, например null, массив или объект, сразу дают 0, даже при непустом $allowed_files. Проверяйте тип и непустое значение отдельно.

$allowed_files(массив)

Разрешённые пути. Каждый элемент нормализуется так же, как $file. Затем выполняется строгое сравнение полного пути с элементами массива. Регистр имён файлов учитывается; шаблоны вроде *.php не поддерживаются.

Пустой массив отключает эту проверку. Наличие пути в списке не отменяет остальные проверки.

По умолчанию: []

Примеры

#1 Демонстрация проверок пути файлов

Путь, который пройдет проверку:

$path = 'uploads/2012/12/my_image.jpg';
echo validate_file( $path ); // выведет 0 (допустимый путь)

Путь, который не пройдет проверку:

$path = '../../wp-content/uploads/2012/12/my_image.jpg';
echo validate_file( $path ); // выведет 1 (недоступный путь)

#2 Домонстрация

echo validate_file( '' );    // 0
echo validate_file( null );  // 0
echo validate_file( false ); // 0
echo validate_file( 0 );     // 0
echo validate_file( [] );    // 0

echo validate_file( 'image.jpg' );          // 0
echo validate_file( 'uploads/image.jpg' );  // 0
echo validate_file( 'uploads//image.jpg' ); // 0
echo validate_file( '/etc/passwd' );        // 0

echo validate_file( '..' );             // 0
echo validate_file( 'uploads/..' );     // 0
echo validate_file( 'uploads/../' );    // 0
echo validate_file( '../' );            // 1
echo validate_file( '../image.jpg' );   // 1
echo validate_file( 'uploads/../x' );   // 1
echo validate_file( 'uploads/../../' ); // 1
echo validate_file( '..\\image.jpg' );  // 1

echo validate_file( 'C:/image.jpg' );   // 2
echo validate_file( 'C:\\image.jpg' );  // 2
echo validate_file( 'C: image.jpg' );   // 2

$allowed = [ 'uploads/image.jpg' ];

echo validate_file( 'uploads/image.jpg', $allowed );   // 0
echo validate_file( 'uploads\\image.jpg', $allowed );  // 0
echo validate_file( 'uploads//image.jpg', $allowed );  // 0
echo validate_file( 'uploads/IMAGE.jpg', $allowed );   // 3
echo validate_file( 'image.jpg', $allowed );           // 3
echo validate_file( '', $allowed );                    // 0
echo validate_file( null, $allowed );                  // 0

echo validate_file( 'image.jpg', [ '*.jpg' ] );        // 3
echo validate_file( '../image.jpg', $allowed );        // 1
echo validate_file( 'C:/image.jpg', $allowed );        // 3

echo validate_file( '../image.jpg', [ '../image.jpg' ] ); // 1
echo validate_file( 'C:/image.jpg', [ 'C:/image.jpg' ] ); // 2

Список изменений

С версии 1.2.0 Введена.

Код validate_file() WP 7.1.3

function validate_file( $file, $allowed_files = array() ) {
	if ( ! is_scalar( $file ) || '' === $file ) {
		return 0;
	}

	// Normalize path for Windows servers.
	$file = wp_normalize_path( $file );
	// Normalize path for $allowed_files as well so it's an apples to apples comparison.
	$allowed_files = array_map( 'wp_normalize_path', $allowed_files );

	// `../` on its own is not allowed:
	if ( '../' === $file ) {
		return 1;
	}

	// More than one occurrence of `../` is not allowed:
	if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) {
		return 1;
	}

	// `../` which does not occur at the end of the path is not allowed:
	if ( str_contains( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
		return 1;
	}

	// Files not in the allowed file list are not allowed:
	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files, true ) ) {
		return 3;
	}

	// Absolute Windows drive paths are not allowed:
	if ( ':' === substr( $file, 1, 1 ) ) {
		return 2;
	}

	return 0;
}
3 комментария