限制文件访问——仅通过 PHP 读取

发布于 2024-09-14 00:02:26 字数 1549 浏览 12 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦幻的味道 2024-09-21 00:02:27

由于您不能将文件放在 public_html 目录之外的任何地方,因此您必须采用令人恐惧/讨厌的“默默无闻的安全”方法

  1. 创建一个随机命名的子目录来存储文件:public_html/ RANDOMGARBAGE

  2. 确保该目录不可浏览。禁用目录浏览(如果可以的话),并在其中放置一个默认文档(index.html?),这样即使浏览打开,您也不会获得目录列表。

  3. 不要使用可猜测的名称存储文件。不要使用数据库 ID 来存储它们,而是使用加盐 + 哈希名称来存储它们: $crypted_filename = sha1($real_filename . '一些难以猜测的盐文本'); (当然,如果需要的话,让它变得更复杂)。将原始文件名存储在数据库中。所以你最终会得到类似的结果:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
    public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. 通过 PHP 脚本提供文件 - 切勿直接链接到哈希文件名

    下载

然后执行:

<?php

    $fileID = (int)$_GET['fileID'];

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text');

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file;
    if (is_readable($full_path)) {
         if(user_is_allowed_to_see_this_file()) {
             /// send file to user with readfile()
             header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME");
             readfile($full_path);
         } else {
             die("Permission denied");
         }
    } else {
        /// handle problems here
        die("Uh-oh. Can't find/read file");
    }

这样用户将永远不会看到您的“s00pereekrit”文件名是什么,他们只会看到他们的浏览器点击 ...php?fileID=37 并开始下载 secret file.pdf

除此之外,您偶尔可以将特殊子目录重命名为某个名称否则定期进行,以及更改盐文本(这需要您使用新的 sha1 值更新所有哈希文件名)。

Since you can't put the files anywhere but in your public_html directory, you'll have to go for the feared/hated "security by obscurity" method

  1. Create a randomly named sub-directory to store the files in: public_html/RANDOMGARBAGE

  2. Make sure the directory is not browseable. Disable directory browsing (if you can), and put a default document (index.html?) in there as well, so even if browsing is on, you won't get the directory listing.

  3. Don't store your files with guessable names. Instead of storing them with the database ID, store them with a salted+hashed name instead: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (of course, make this more complex if you need to). Store the original filename in your database. So you end up with something like:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
    public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. Serve up the files via a PHP script - never link to the hashed filename directly

    Download

which then does:

<?php

    $fileID = (int)$_GET['fileID'];

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text');

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file;
    if (is_readable($full_path)) {
         if(user_is_allowed_to_see_this_file()) {
             /// send file to user with readfile()
             header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME");
             readfile($full_path);
         } else {
             die("Permission denied");
         }
    } else {
        /// handle problems here
        die("Uh-oh. Can't find/read file");
    }

This way the user will never see what your "s00per seekrit" filename is, they'll just see their browser hit ...php?fileID=37 and start a download of secret file.pdf

On top of this, you can occasionally rename the special sub-directory to something else on a regular basis, as well as change the salt text (which then requires you update all the hashed filenames with the new sha1 values).

再浓的妆也掩不了殇 2024-09-21 00:02:27

您可以简单地隐藏它们。这是通过默默无闻实现安全性,但如果您无法将它们排除在网络根目录之外,或者找到一种方法告诉服务器不要直接为它们提供服务,那么这听起来是您的最佳选择。

因此,将它们放在某个随机命名的目录中:

asd8b8asd8327bh/123.pdf
asd8b8asd8327bh/124.pdf
asd8b8asd8327bh/125.pdf
...

然后自己编写一个 PHP 脚本,该脚本将发送适当的标头,并传递文件内容。

例如:

<?PHP
//pdf.php
$id = $_GET['id'];

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers.
if (!some_validation_passes($id)){
  die();
}
<?php

header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$id.'.pdf"');
readfile('asd8b8asd8327bh'.$id.'pdf');

现在,上面的内容实际上并不比直接提供文件更好,因为人们仍然可以增加查询字符串中的 id 参数。

但您应该能够弄清楚如何轻松处理授权。

You can simply hide them. It's security-through-obscurity, but it sounds like your best option if you can't either keep them out of the web-root, or find a way to tell the server not to serve them directly.

So stick them in some randomly-named directory:

asd8b8asd8327bh/123.pdf
asd8b8asd8327bh/124.pdf
asd8b8asd8327bh/125.pdf
...

Then write yourself a little PHP script that will send appropriate headers, and pass the file contents through.

for example:

<?PHP
//pdf.php
$id = $_GET['id'];

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers.
if (!some_validation_passes($id)){
  die();
}
<?php

header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$id.'.pdf"');
readfile('asd8b8asd8327bh'.$id.'pdf');

Now, the above is really no better than just serving the files directly (yet), since people can still increment the id parameter in the query string.

But you ought to be able to figure out how to handle authorization pretty easily.

岁月如刀 2024-09-21 00:02:27

由于 PHP 使用 Web 服务器用户的权限,因此无法限制对文件的访问,除非执行以下操作:

  • 将它们放在 DOCROOT 之外
  • 更改 Web 服务器配置以禁止访问这些文件
  • 更改文件,以便由 Web 服务器解释该文件,从而隐藏其内容

将它们放入数据库中算作在 DOCROOT 之外。对于第三个选项,您可以制作 PDF PHP 文件,但说实话,这会非常复杂。

我建议您联系 GoDaddy 并查看他们是否有某种方法来配置每个目录的文件权限。

Because PHP uses the web server user's permissions, there is no way to restrict access to the files without either:

  • Placing them outside the DOCROOT
  • Changing the web server configuration to disallow access to those files
  • Changing the file so it will be interpreted by the web server, thus hiding its contents

Putting them in a database counts as outside the DOCROOT. For the third option, you could make the PDFs PHP files, but honestly, that would be pretty convoluted.

I recommend you contact GoDaddy and see if they have some way to configure per-directory file permissions.

吻风 2024-09-21 00:02:27

通过 chmod 使文件夹 web 不可访问。 PHP 仍然能够包含/需要服务器上的任何内容,但用户将无法导航到这些文件。

例子:
这里设置为770,IE用户和组可以读/写/执行,其他不能做任何事情。

Make a folder web inaccessable via chmod. PHP will still be able to include/require whatever is on the server, but users will not be able to navigate to the files ever.

Example:
This is set to 770, IE User and Group can Read/Write/Execute, Other can do nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文