Route::get('/transaction/{name}', 'TransactionController@download');
public function download($name){
$path = storage_path('app/something/') . $name . '.xml';
return response()->download($path);
}
用户只能使用此操作在app / something中下载.xml文件。
是否可以在指定的app/something
文件夹之外下载数据。
答案 0 :(得分:2)
Laravel无法防止遍历攻击 - 路由器将使用您的代码示例返回任何值,这意味着有人可以访问您的文件系统!
您可以通过从字符串中删除任何路径引用来使用PHP basename()
来清理$name
:
Route::get('/transaction/{name}', 'TransactionController@download');
public function download($name){
$path = storage_path('app/something/') . basename($name, '.xml') . '.xml';
return response()->download($path);
}
答案 1 :(得分:1)
更新回答
正如您在下面所看到的,它确实可以在Laravel路线中做恶意内容。鉴于你的功能设置,某人做你不想要的事情的机会很小,因为他/她只能改变$name
变量。
您仍然可以编写一些额外的代码(在viblo.asia上找到):
$basepath = '/foo/bar/baz/'; // Path to xml file
$realBase = realpath($basepath);
$userpath = $basepath . $_GET['path'];
$realUserPath = realpath($userpath);
if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {
//Directory Traversal!
} else {
//Good path!
}
为了防止用户访问他们不允许访问的文件。
陈旧但相关的答案
刚在Homestead尝试过这个:
Route::get(
'/',
function () {
dump(exec('ls ' . storage_path() . '/../../../'));
}
);
然后打印相应的文件夹就好了:
所以我说它绝对有可能在指定文件夹之外做些事情。例如,为自己尝试一下:
Route::get(
'/',
function () {
for ($i = 0; $i < 10; $i++) {
$path = str_repeat('/..', $i);
dump(exec('ls ' . storage_path() . $path));
}
}
);
当您点击/
路线时,看到您的文件夹出现在屏幕上。
答案 2 :(得分:1)
据我所知,Laravel将编写您的路径:
#^/transaction/(?P<name>[^/]++)$#s
这么简单/不会起作用.. 您可以使用更复杂的反斜杠 - 但这取决于服务器..
最后 - 记住不要相信所有用户输入..无论是通过路由还是直接接收..