如何允许用户下载存储在 webroot 之外的文件?

2021-12-24 00:00:00 file-upload download security php

我正在开发一个允许注册用户(可以是任何人)上传文件的系统.我阻止了 mime 类型等,试图将文件限制为 .doc、.docx 和 .pdf 类型,但为了提高安全性,它们被上传到 webroot 之外的文件夹.

I am developing a system which allows registered users (who could be anybody) to upload files. I've block mime-types etc. to attempt to restrict the files to .doc, .docx and .pdf types, but for additional security, they are uploaded to a folder outside the webroot.

其他用户可以选择下载文件.我如何允许他们这样做?显然,我不能只添加指向该文件的链接,因为它在 webroot 之外.我不确定如何访问该文件!我想我可以使用 php 文件函数来访问该文件,但是我如何将它提供"给请求它的用户?

Other users can then choose to download the files. How do I allow them to do that? Obviously I can't just put in a link to the file, as it's outside the webroot. I'm not sure how to reach the file though! I presume I can use the php file functions to get to the file, but how do I then 'serve it up' to the user who has requested it?

这一切可能会带来哪些安全隐患?

What security implications might all of this have?

谢谢.

推荐答案

您需要一个执行以下操作的 PHP 脚本:

You need a PHP script that does the following:

  1. 正确设置内容类型标头(取决于用户正在下载的内容)
  2. 正确设置内容长度标头(取决于文件大小)
  3. 打开文件进行读取(可以使用fopen)
  4. 读取文件并将其内容输出到输出流
  5. 完成

您也可以使用 readfile 函数来做基本相同的事情.这是 PHP 网站上的一个示例:

You can also use readfile function to do basically the same. Here's an example from PHP's site:

<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}
?>

相关文章