Я создаю базовый PHP-источник для папки кода примера моего блога.
<?php if (isset($_GET['file'])) { header('Content-type: text/plain'); $filename = realpath($_GET['file']); if (startsWith($filename, dirname(__FILE__))) { echo file_get_contents($filename); } } function startsWith($haystack, $needle) { $length = strlen($needle); return (substr($haystack, 0, $length) === $needle); } ?>
Есть ли у меня здесь достаточно, чтобы он никогда не позволял просматривать файл за пределами каталога, в котором находится этот скрипт, или подкаталогов каталога этого скрипта? Я предполагаю, что есть лучшее решение, чем startsWith, для проверки того, является ли путь потомком определенного каталога?
Да, это будет безопасно. Часть realpath
– это то, что вам нужно делать, и вы это делаете. Этот код делает то, что он должен просто отлично.
Возможно, вы уменьшите ввод до имени файла (см. Finfo ) и укажите каталог для поиска, если он является одним и тем же каталогом каждый раз, поэтому вам не нужно проверять через startsWith()
.
Если вы хотите показать только PHP-исходный код, попробуйте включить * .phps-file-handling в своем веб-сервере. См. https://serverfault.com/questions/62410/apache-htaccess-phps.
В стороне, посмотрите на использование strncmp вместо вашей пользовательской функции startWith.
Если бы я подошел к подобному проекту, я бы:
Используйте комбинацию вашего решения & htaccess, чтобы замаскировать исходное имя файла как имеющее:
http://example.com/viewsource.php?file=./project1/index.php
было бы слишком очевидным и соблазнительным, чтобы с ним связать, используя htaccess, который у вас может быть:
http://example.com/source/project1/index.php
это тоже указывает
h1ddEnfIlEs / ViewSource / index.php? Файл = $ 1 и папка = $ 2
RewriteRule ^source/([a-z0-9]+)/([a-z0-9]+).php$ h1ddEnfIlEs/viewSourceScript/index.php?file=$2&project=$1
Затем с помощью средства просмотра источника h1ddEnfIlEs / viewSourceScript / index.php
<?php if( is_dir('./h1ddEnfIlEs/'.$_GET['project'].'/')===true && is_file('./h1ddEnfIlEs/'.$_GET['project'].'/'.basename($_GET['file'])) ){ highlight_file('./h1ddEnfIlEs/'.$_GET['project'].'/'.basename($_GET['file'])); } ?>