0

我的 PHP 应用程序有一个文件控制器。经过身份验证的用户下载的每个文件都应首先通过文件控制器。

作为参数,我使用文件 inode 以便它可以在磁盘内正确定位文件,并且可以通过 URL 安全地传递它(因为它只是数字——我不必担心 UTF-8 文件名和在这里)。

这些文件是从文件系统中读取的,而不是从数据库中读取的,因此数据尽可能是实时的。

泄露我的文件系统的 inode 是一种安全威胁吗?通过 inode 定位文件是一种不好的做法?

权限检查:

我使用 Codeigniter 作为框架。通过扩展核心控制器类和 _remap() 方法,我可以检查每个控制器调用的访问文件控制器的人是否已登录。

如果是(并且角色具有权限),则允许下载。如果不是,则重定向到登录。

在相同的 inode 上:

我没有进行完整的文件系统扫描。我在文件系统中列出了一个目录,由上传者划分,然后由操作 id 划分(所以基本上,每个文件夹将有 10 个文件,取决于参数)。结构基本上是:

module/module_id/user_id/files

我猜在同一个文件夹中不能有两个具有相同inode的文件,如果另一个文件系统中有另一个文件(或者在同一个文件系统中,我不清楚是否可能),那么它不在同一个文件夹中,因此,该参数链无法访问。

例如(假设我们想要获取一个带有 inode #5243376 的文件):

模块/1/3/5243376

如果有另一个 inode 为 5243376 的文件,该文件必须位于文件夹 module/1/3/ 中,以便可以下载。

我看不到任何其他获取相同(或另一个文件)的方法,因为控制器会处理它。

处理程序的代码很简单:

// match inode
$dir    = FCPATH . 'files/' . $type . '/' . $id . '/'. $user . '/';
$files  = scandir($dir);

foreach($files as $file) {
    $stat = stat($dir . $file);
    if ($inode == $stat['ino']) {
        $filename = $file;
    }
}

// this need better feedback lol
if (!isset($filename)) {
    die('Not existing');
}

// fullpath to file to be downloaded
$file = FCPATH . 'files/' . $type . '/' . $id . '/'. $user . '/' . $filename;
4

1 回答 1

3

它没有什么问题。即使您只处理 inode,基本文件系统安全性仍然适用。但是您应该意识到 inode 在操作系统中可能不是唯一的。它们仅在特定文件系统中是唯一的。如果您的主机系统在您的 Web 根目录中有多个挂载的 FS,如果移动跨越文件系统边界,则将文件移动到不同的目录实际上可能成为复制 + 删除操作。现在您的 inode 不再有效,因为在新位置创建了一个新的 inode。

于 2012-09-18T18:00:51.317 回答