【问题标题】:PHP Download Script with mod-xsendfile Implementation带有 mod-xsendfile 实现的 PHP 下载脚本
【发布时间】:2023-03-23 13:47:01
【问题描述】:

我目前正在使用this PHP 下载脚本从我的网站上提供一长串大文件 (1GB+),但在抱怨下载损坏后,我研究并找到了一个更好看的替代方案:mod_xsendfile。我的主机是 Dreamhost,他们已经在我的域上启用了 xsendfile。我使用作者网站上的这段代码对其进行了测试,并且可以正常工作:

<?php 
header("X-Sendfile: /home/username/website.com/test.zip");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=test.zip");
exit;
?>

但我希望将所有下载内容放在一个目录中并链接到文件,就像我使用媒体部门的脚本一样:

https://website.com/download.php?file=test.zip

我搜索了大多数带有 x-sendfile 标记的问题,但没有发现任何有用的信息。我不会编写 PHP 代码,但知道足以配置脚本以使它们工作。有谁知道可以执行此操作或可以帮助我的脚本吗?

谢谢

【问题讨论】:

    标签: php download dreamhost x-sendfile


    【解决方案1】:

    可以这样做:

    <?php 
    $path = realpath("/home/username/website.com/" . $_GET["file"]);
    if (strpos($path, "/home/username/website.com/") !== 0) {
        header("Status: 404 Not Found");
        die();
    }
    header("X-Sendfile: $path");
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=".$_GET["file"]);
    

    这也确保用户无法从除/home/username/website.com/ 之外的任何其他目录获取文件,例如数据库备份或您不想下载的其他内容。

    【讨论】:

    • 效果很好,谢谢!我没有使用完整路径,而是将其更改为:$path_to_file = 'files/'; header("X-Sendfile: $path_to_file".$_GET["file"]); 这似乎工作正常,因为我在“文件”目录中有我想要链接到的所有下载。另外,有没有办法能够链接到文件目录中的子目录?类似:https://website.com/download.php?file=subdir/test.zip
    • 我知道这是一个旧线程,但对于后代:确保$_GET['file'] 已正确转义。如果不是,用户可以从文件系统请求任何文件。例如通过请求../../../../etc/passwd
    • @mike 这就是为什么我检查文件名中是否有 / 的原因。使用此脚本不可能进行这样的攻击。
    • 在类 Windows 系统上仍然可以进行攻击。
    • 在 Unix 风格的系统上也可以使用 file 查询:%2e%2e%2fetc%2fpasswd 变成 ../etc/passwd。如果您不知道您的代码的真正用途,则不应向任何人提供有关安全性的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多