django - 在提供机密媒体文件时,Web 应用程序应如何确保安全?
问题描述
问题:假设用户上传高度机密的信息。这被放置在第三方存储服务器中。此第三方存储桶对 Web 应用程序使用不同的身份验证系统。确保只有用户或管理员才能访问文件 url 的最佳做法是什么?
更多上下文: Django Web 应用程序在 Google App Engine Flexible 上运行。Google Storage 用于通过 Django 提供静态和媒体文件。高度机密的信息是护照、法律合同等。
静态文件以相当不安全的方式提供。存储桶是公共的/static/
,文件通过 django 的静态文件系统提供服务。这有效,因为
- 我们的任何静态文件中都没有机密或用户信息
,只有库存图片、css 和 javascript,以及 - 这些文件在生产前被丑化和缩小。
但是,对于媒体文件,我们需要用户特定的权限,如果用户 A 上传了图像,那么用户 A 可以查看它,工作人员可以查看它,但是用户 B 和未经身份验证的用户在任何情况下都无法查看它。这包括他们是否有网址。
我的首选系统是,GCP 存储可以使用相同的 django 身份验证服务器,因此当浏览器请求时...google.storage..../media/user_1/verification/passport.png
,我们可以检查该用户拥有的权限,将其与上传的用户 ID 进行比较,并决定是否显示 403 或实际文件。
这个问题的行业标准/最佳实践解决方案是什么?
我是否让应用程序只能使用服务帐户访问这两个存储桶,并确保只有在正确的用户正在查看页面时才在内部共享链接?(任何人都是静态的,{user or staff} 是媒体?)
我的问题,特别是(关于 Web 应用程序安全性):
- 从公开可读的存储桶中提供静态文件是否安全?
- 可以假设如果我的应用程序请求文件 url,这是来自经过身份验证的用户吗?
- 特别是关于 Django 和 GCP 存储,如果 2 为假(我相信是),我如何确保从存储桶提供的文件仅对具有正确权限的用户可见?
解决方案
- 是的。公共可读的存储桶就是为此而生的。诸如 CSS、您公司的徽标或一些没有敏感数据的文件之类的东西可以安全地共享。
当然,不要使用同一个公共存储桶来存储私有/公共的东西。公共与公共,私人与私人。
- 这是问题所在。当您说“经过身份验证的用户”时,您希望该用户向谁进行身份验证?
例如,如果您使用任何Django 方法对用户进行身份验证,则该用户将通过 Django 身份验证,但对于 Cloud Storage,它将是一个陌生人。此外,即使是在 GCP 上授权的用户也可能无权访问 Cloud Storage 上的存储分区。
这里重要的是,与 Cloud Storage 来回通信的不是用户,而是它的 Django。它可以通过使用Cloud Storage 的 python SDK来实现这一点,该 SDK采用实例上正在使用的服务帐户的凭据来验证对 Cloud Storage 的任何请求。因此,运行 VM 的服务帐户(因为您处于灵活状态)是应该被授权到云存储的服务帐户。
- 您必须首先在 Django 上授权用户,然后检查用户是否能够通过其他方式访问此文件(例如将他上传的文件的名称存储在 user_uploaded_files 表中)。
关于帖子顶部的第一个问题,Cloud Storage 允许您创建签名的 url。此 url 允许 Internet 上的任何人只需持有该 url 即可从 Cloud Storage 上传/下载文件。所以你只需要在 Django 上授权用户获取签名的 url 就可以了。他不需要在 Cloud Storage 上获得“授权”(因为 url 已经这样做了)
取自之前链接的文档:
什么时候应该使用签名 URL?
在某些情况下,您可能不希望您的用户必须拥有 Google 帐户才能访问 Cloud Storage,但您仍希望使用特定于应用程序的逻辑来控制访问。解决此用例的典型方法是向用户提供签名的 URL,这使用户可以在有限的时间内读取、写入或删除对该资源的访问权限。知道 URL 的任何人都可以访问该资源,直到 URL 过期。您在要签名的查询字符串中指定到期时间。
推荐阅读
- terminal - 尝试启动 Virtual Box 时如何解决这些错误?
- java - 从类中调用方法与创建类和调用方法有何不同?
- vue.js - 在 SASS 中使用 Vuetify 类
- php - 无法声明类 symfony 3
- swift - 可以将 Swift 枚举作为变量引用吗?
- c++ - 如何在c ++中修复超出范围的向量下标
- javascript - 反应路由器显示根组件以及路由路径
- php - 插入数据时如何检查数据是否已经存在
- javascript - Javascript 代码不适用于 IE11,但适用于所有其他浏览器
- reactjs - ASP.NET Core 项目 React 中的 ES6 模板文字(模板字符串)