readfile() - 只允许从某些目录下载某些文件类型
我正在创建的网站上有文件夹,我只希望登录用户能够访问其中的文件。因此,我决定使用一些 .htaccess 规则和 PHP 文件处理程序,以便确保用户在访问文件之前已登录。文件处理程序将以“/download.php?file=filename.pdf”的形式接受输入。我只希望用户能够下载Word文档和PDF文件。如何使用户无法通过下载网站的 .php 文件或下载这些目录之外的文件来滥用我的文件处理程序?
I have folders on a website I am creating that I only want logged in users to be able to access the files from. So, I've decided to use some .htaccess rules and a PHP file handler so I can make sure users are logged in before they can access the files. The file handler will take input in the form of "/download.php?file=filename.pdf". I only want the user to be able to download Word documents and PDF files. How do I make it so users can't abuse my file handler by downloading things like the .php files for my website or downloading files outside of those directories?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,我要指出的是,这样做可能不安全。尽管如此,它是一种常见的程序类型。文件处理程序应该清理用户输入。首先,您应该在能力有限的单独帐户上运行您的网络服务器。这样,如果黑客可以尝试访问您的文件系统,他们就已经受到严格限制。然后,您应该更改下载文件夹之外的所有内容的权限。
现在,您有几个选项可用于清理要下载的文件的用户输入。
您可以使用 Perl Regex 来查找扩展名。
您可以使用 pathinfo() 来获取基本名称和扩展名...这样您就不会打开任何目录(例如 ../ 或 /home 等)。
您可以在数据库中为每个文件提供一个 id,然后让文件处理程序执行类似 /download.php?file=12345 的操作,但您必须清理数据库的用户输入。
Well, I was going to note that this can be insecure to do. Nonetheless, it is a common type of program. The file handler should clean the user input. First of all, you should be running your web server on a separate account with limited abilities. That way, if the hacker can try to access your filesystem, they are already severely limited. Then, you should change the permissions of everything outside of the download folder.
Now, you have a couple options for cleaning the user input for which file to download.
You could use Perl Regex to find the extension.
You could use pathinfo() to get the basename and extension...this way you would not open any directory (like ../ or /home etc).
You could give each file an id in a database and then instead have the file handler do something like /download.php?file=12345 but you would have to clean the user input for the database.
在提供文件下载之前清理该值。检查它的父遍历并验证文件扩展名。
Sanitize the value before offering the file for download. Check it for parent traversal and verify the file extension.
其一,不要直接公开正在下载的文件的名称。使用某种哈希令牌。理想情况下,您将保留数据库中所有可能文件的列表,并使用记录主键的加盐+哈希副本作为文件的客户端标识符。所以
用户会看到
而不是相反。
在 download.php 脚本中,您执行适当的检查 - 此人是否有权查看该文件,是否允许他们下载此文件类型等...如果不允许,您将输出一个错误页面。如果是,则输出带有适当标头的文件,以便他们获得原始文件名,而不是散列垃圾或“download.php”
For one, don't directly expose the name of the file being downloaded. Use a hashed token of some sort. Ideally, you'd keep a list of all the possible files in the database, and use a salted+hashed copy of the record's primary key as the client-side identifier of the file. So instead of
the user will see
instead.
And inside the download.php script, you do the appropriate checks - is this person cleared to see the file, are they allowed to download this file type, etc... if they're not, you output an error page. If they are, you output the file, with the appropriate header so they'll get the original filename and not the hashed garbaged or "download.php"