laravel的路由是否足以抵御文件遍历攻击?

时间:2017-01-19 08:19:38

标签: laravel security

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文件夹之外下载数据。

3 个答案:

答案 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() . '/../../../'));
    }
);

然后打印相应的文件夹就好了:

enter image description here

所以我说它绝对有可能在指定文件夹之外做些事情。例如,为自己尝试一下:

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

这么简单/不会起作用.. 您可以使用更复杂的反斜杠 - 但这取决于服务器..

最后 - 记住不要相信所有用户输入..无论是通过路由还是直接接收..