Web 应用程序在提供机密媒体文件时应如何确保安全?

Hen*_*rge 6 media django google-app-engine google-cloud-storage google-cloud-platform

问题:假设用户上传高度机密的信息。这被放置在第三方存储服务器中。此第三方存储桶对 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 或实际文件。

此问题的行业标准/最佳实践解决方案是什么?

我是否可以使用服务帐户使两个存储桶只能由应用程序访问,并在内部确保仅当正确的用户正在查看页面时才共享链接?(有人喜欢静态,{用户或工作人员}喜欢媒体吗?)

我的问题,特别是(关于网络应用程序安全性):

  1. 从公共可读存储桶提供静态文件是否安全?
  2. 是否可以假设,如果我的应用程序请求一个文件 url,该文件来自经过身份验证的用户?
  3. 特别是关于 Django 和 GCP 存储,如果 2 为假(我相信是),我如何确保从存储桶提供的文件仅对具有正确权限的用户可见?

Nah*_*ela 4

  1. 是的。公共可读的存储桶就是为此而设计的。CSS、公司徽标或一些没有敏感数据的文件可以安全地共享。

当然,不要使用同一个公共存储桶来存储私有/公共内容。公对公,私对私。


  1. 问题就在这里。当您说“经过身份验证的用户”时,您希望该用户向谁进行身份验证?

例如,如果您使用任何Django 方法对用户进行身份验证,那么该用户将通过 Django 进行身份验证,但对于 Cloud Storage 来说,这将是一个陌生人。此外,即使是在 GCP 上授权的用户也可能无权使用 Cloud Storage 上的存储桶。

这里重要的是,与 Cloud Storage 来回通信的不是用户,而是 Django。它可以通过使用Cloud Storage 的 python SDK来实现这一点,该 SDK 使用实例上使用的服务帐户的凭据来验证对 Cloud Storage 的任何请求。因此,运行虚拟机的服务帐户(因为您处于“灵活”状态)应该被授权使用 Cloud Storage。


  1. 您必须首先在 Django 上授权用户,然后检查用户是否能够通过其他方式访问该文件(例如将他上传的文件的名称存储在 user_uploaded_files 表中)。

关于帖子顶部的第一个问题,Cloud Storage 允许您创建签名 url。此网址允许互联网上的任何人只需持有该网址即可从云存储上传/下载文件。所以你只需要在Django上授权用户获取签名的url就可以了。他不需要在云存储上获得“授权”(因为url已经这样做了)

摘自之前链接的文档:

什么时候应该使用签名 URL?

在某些情况下,您可能不希望要求用户拥有 Google 帐户才能访问 Cloud Storage,但您仍然希望使用特定于应用程序的逻辑来控制访问。解决此用例的典型方法是向用户提供签名 URL,该 URL 为用户提供在有限时间内对该资源的读取、写入或删除访问权限。知道该 URL 的任何人都可以访问该资源,直到该 URL 过期。您在要签名的查询字符串中指定过期时间。