【问题标题】:Safe way to access files outside /var/www [duplicate]访问 /var/www 之外的文件的安全方法 [重复]
【发布时间】:2014-04-28 16:45:35
【问题描述】:

大家好,

我有一个棘手的问题,我自己也弄不明白。

我制作了一个网页,人们可以在其中上传不同类型的文件。这些文件被重命名 - 新文件名存储到数据库中 - 并移动到 /home/myname/newfilename.xyz

所以我专注于确保这些上传内容尽可能安全,并防止自己让人们上传“邪恶”文件并以某种方式执行它们。

我还做了一种后端,我可以在其中查看所有上传的文件 - 我想链接这些文件以便我可以查看/下载它们,但由于它们不在 /var/www 目录中,我无法访问它们通过像“../../../home/myname/newfilname.xyz”这样链接它们。我知道有不同的方法可以完成一个循环,但在我做某事之前,我想知道是否有人知道最安全的方法。

如果这里有人可以帮助我,那就太好了:)

干杯

【问题讨论】:

  • 我还会建议其他一些事情。限制用户可以上传的文件类型。并将文件夹上的服务器属性设置为只读/写,因此它们无法执行。
  • 嗯,它与链接的主题不重复。我必须保持写权限,这样我才能让我的脚本将文件上传到那里对吗?所以我不能只追求“阅读”权利,或者我在这里有什么问题吗?

标签: php apache file security


【解决方案1】:

实现此目的的一种方法是使用 PHP “流式传输”文件。您将文件引用存储在db中,也许您可​​以通过id而不是文件名来引用文件?

假设您创建了这个 PHP 脚本:

http://mysite/downloadFile.php?fileId=1000

然后你可以通过这样的方式来实现它:

$fileId = $_GET['fileId'];
$fileinfo = getfilenamefromdb($fileId); // fetch filename and mime type from db
if (!$fileinfo) die('File not found');

// access control?

header('Content-type: '.$fileinfo['mimetype']);
$content = file_get_contents('/home/myname/'.$fileinfo['filename']);
echo $content;

您必须实现getfilenamefromdb() 功能,并可能实现访问控制。通过 id 引用将阻止某人通过请求 ../../../etc/passwd 之类的文件来访问您的文件系统

【讨论】:

  • 是的,我还有唯一 ID,它们是我的主键。您的解决方案看起来不错并且看起来很合乎逻辑 - 将对其进行测试并告诉您它是如何进行的。 :)
  • 太棒了。您可以在文件上传时访问 mime 类型。否则周围有大量的文件扩展名到mime-type-libraries。
  • php.net/manual/de/function.mime-content-type.php - 在这个话题上帮了我很多谢谢你的帮助是一种祝福!