#php
#php
Вопрос:
Каковы риски, связанные с выполнением чего-то подобного? Например, могут быть некоторые специальные символы, которые будут проходить проверки, позволяют пользователю включать нежелательные файлы или заставлять используемые здесь функции php работать неправильно или вести себя не так, как задумано, о чем я должен знать.
//parse the uri
$uri=trim(parse_url(urldecode($_SERVER['REQUEST_URI']))['path'],'/');
$path=saferDirnameAndBasename($uri);
$class=$path->dir;
$method=$path->base;
//or it could be done with url rewritting, or just parameters, like:
//$class=$_GET['c'];
//$method=$_GET['m'];
$class=filter_var($class,FILTER_UNSAFE_RAW,FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH);
$method=filter_var($method,FILTER_UNSAFE_RAW,FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH);
if(preg_match('/[^a-z0-9_/-]/i',$class)||preg_match('/[^a-z0-9_]/i',$method)) exit;
$file=__DIR__.'/folder-where-public-clases-are/'.$class.'.php'; //note that it's allowing subdirs, but I don't want the user to go up
if(!file_exists($file)) exit;
include_once($file);
//remove the dashes too, my-class.php should contain myclass
$class=str_replace('-','',$class);
$path=saferDirnameAndBasename($class);
$namespace='\publicClasses\'.str_replace('/','\',$path->dir); //dir/class -> publicClassesdir
$name=$path->base;
$fullname=$namespace.'\'.$name;
if(!class_exists($fullname)) exit;
$obj=new $fullname;
if(!method_exists($obj,$method)) exit; //I know this doesn't account for visibility prior to php 7.4
call_user_func([$obj,$method]);
function saferDirnameAndBasename($path) {
$parts=explode('/',$path);
return (object)[
'base'=>array_pop($parts),
'dir'=>implode('/',$parts)
];
}
Файл в folder-where-public-clases-are
будет содержать
<?php
namespace publicClasses;
class myclass {
public function test() {
}
}
Это создало бы динамический маршрутизатор, где пути не должны быть определены заранее. Частный код должен просто находиться за пределами publicClasses
пространства имен.
Комментарии:
1. «Каковы риски, связанные с выполнением чего-то подобного?» — огромный .
2. Что вы имеете в виду?
3. В строке 2 вашего скрипта непроверенный пользовательский ввод передается непосредственно в
dirname
— я сдался в этот момент. Смотрите здесь: acunetix.com/websitesecurity/php-security-24. Ваш скрипт пытается очистить вводимый пользователем для имени файла с помощью регулярного выражения, но легко обойти большинство фильтров, налагаемых регулярными выражениями для имен файлов (подсказка: триграфы). Ваш скрипт обречен. ОБРЕЧЕН, Я ВАМ ГОВОРЮ!
5. Ну, это не производственный код, я написал его быстро, чтобы вызвать такого рода ответы.
dirname
иbasename
может быть легко заменен. Регулярные выражения были моей главной заботой. Спасибо.