根据 Django 文档:“将静态资产与用户上传的文件一起放置在 MEDIA_ROOT 中是很常见的,并在 MEDIA_URL 上同时提供它们。”
这是否意味着每个人都可以访问其他人上传的文件?不是不安全吗?
根据 Django 文档:“将静态资产与用户上传的文件一起放置在 MEDIA_ROOT 中是很常见的,并在 MEDIA_URL 上同时提供它们。”
这是否意味着每个人都可以访问其他人上传的文件?不是不安全吗?
聪明的用户可能会猜出属于其他用户的媒体文件的路径。
Django 诞生于新闻出版行业,这并不令人担忧:管理员基于受信任用户的概念,例如属于同一组织的作家和编辑。
不是我的第一选择,但您可以让网络服务器针对 Django 的用户数据库进行身份验证:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
<Location "/media/private-user-content/">
AuthType Basic
AuthName "Top Secret"
Require valid-user
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
</Location>
接受的答案建议从经过身份验证的 Django 视图中提供敏感文件。对于低流量的应用程序来说是可以的,但对于大型项目来说,它带来的性能损失并不是每个网站都能承受的。
出于性能和成本考虑,大型项目应该使用一些云存储后端。如果您的项目已经托管在三大巨头(AWS、GCP、Azure)中,请检查Django Storages。例如,如果您使用的是 S3 后端,则可以为生成的 URL 开启“查询参数身份验证”,瞧,问题就解决了。这有一些优点:
对于您从同一个网络服务器提供媒体和应用程序的小型项目,您可以让爱管闲事的用户很难找到不属于他们的媒体文件:
1) 在 MEDIA_ROOT 文件夹中禁用 Web 服务器“自动索引”。对于 apache,它就像:
<Directory /path/to/application/media/root>
Options -Indexes
</Directory>
如果没有索引,为了访问属于其他人的文件,您将不得不猜测确切的文件名。
2) 使用 FileFields 的“upload_to”参数中的加密哈希使文件路径难以猜测:
def hard_to_guess(instance, filename):
salt = 'six random words for hidden salt'
hash = hashlib.md5(instance.user.username + salt)
return '/'.join(['content', hash, filename])
...
class SomeModel(models.Model):
...
user = models.ForeignKey(User)
content = models.FileField(upload_to=hard_to_guess)
...
此解决方案不会影响性能,因为媒体文件仍直接从网络服务器提供。
回答您的问题:是的,这将允许每个人访问每个人上传的文件。是的,这是一个安全风险。
作为一般规则,不应直接从文件系统提供敏感文件。作为另一条规则,除非另有明确标记,否则所有文件都应被视为敏感文件。
MEDIA_ROOT
和设置的起源MEDIA_URL
可能在于 Django 作为发布平台的历史。毕竟,您的编辑可能不会介意他们添加到文章中的图片是否可以轻松找到。但话又说回来,文章附带的图片通常是非敏感的。
扩展您的问题:敏感文件应始终放置在 Web 服务器无法直接访问的目录中。请求这些文件只能通过视图类或函数来完成,它可以在提供文件之前进行一些合理的访问检查。
此外,不要依赖混淆敏感文件。例如,让我们使用 Paulo 的示例(请参阅其他答案)来混淆相册。现在我的图片存储为MEDIA_URL/A8FEB0993BED/P100001.JPG
. 如果我与其他人共享此链接,他们可以轻松尝试类似的 URL MEDIA_URL/A8FEB0993BED/P710032.JPG
,基本上可以让他们暴力破解我的整个相册。