php - 使用用户提供的名称保护 PHP 文件的上传和下载
问题描述
我正在编写一个文件转换器。因此,用户上传文件,例如,该文件test.txt
随后被转换,并且下载链接被发送回用户。出于安全目的,我在上传文件后立即更改文件的名称,就像这里也建议的那样。
Instead create files and folders with randomly generated names like fg3754jk3h
问题从下载开始。为了获得更好的用户体验,我希望可下载的文件与用户提供的文件具有相同的名称,而不是随机字符串。目前我在 Chrome 中也遇到了一个错误:
<Filename> is an unusual download and may be harmful. [translated]
我认为这也可能是加密文件名的结果。
所以我的问题是:在没有任何安全问题的情况下将文件名更改回原始文件名的最佳方法是什么,或者我应该更好地对文件名进行严格验证?这会摆脱显示的错误消息吗?
解决方案
您可以在将文件返回给用户时提供原始文件名。(请参阅下载名称与存储名称不同的文件以了解一些方法)
不以原始名称存储文件的原则是避免恶意用户试图将某些脚本上传到您的服务器,他可以执行。您应该这样做,但也应该将这些文件放在您的 Web 服务器无权访问的临时目录中。
例如:
- 您的网络服务器指向
/var/www
- 当您收到上传的文件时,将其存储在
/var/uploads
而不是/var/www/uploads
. 这样,用户将永远无法访问该文件(至少从网络) - 您将原始文件名保存在数据库中
- 您仍然应该生成一个随机文件名,这将避免文件名冲突(很多人会上传他们的
cute-cat.jpg
图像),保持文件扩展名没有问题。例如:kr3242sd93fdsh.jpg - 您通过一些随机字符串为您的用户提供一些端点下载文件(我建议您避免使用用于命名文件的相同随机字符串):https ://youserver.com/download?id=uoqq41jsak
Content-Disposition
在您的下载端点上,您在的filename
属性上定义原始文件名。
推荐阅读
- sql - T-SQL - 将更多日期值添加到表中的所有行
- docker - 如何在 Docker 和主机上处理同一非 root 用户的权限?
- swift - Tableview 只允许有限的复选框按钮
- python - 我无法从 python 连接 pwnedpasswords API
- python - 从列表中的网站抓取图像
- angular - Angular 8:使用 addControl 方法时传递禁用属性不起作用
- javascript - TypeError:无法读取 nodeJS 中未定义的属性“findIndex”
- javafx - JavaFX的WebEngine中选择元素显示错误
- javascript - 我在 node.js 中使用 Promise 的错误在哪里
- javascript - 自 2 月 20 日起适用于第 3 方 cookie 的 Samesite 和 Secure