安全地为多个客户端存储和提供文件


8

我们正在开发一个网络应用程序,其中(除其他功能外)我们的用户可以上传他们的文件。但是,由于存储空间有限,我们无法将这些文件存储在VPS上,因此我们决定使用S3。

主要问题是我们必须确保用户只能访问自己的数据。因此,我们将文件列表保存在数据库中,并将有权访问这些文件的用户列表保留在数据库中。我们的服务器可以轻松决定用户是否有权访问文件。但是如何实际将文件提供给用户呢?

我已经考虑过一些可能性,但是似乎没有一个是最好的。

1.使用PHP生成(过期)签名的URL

这是一种非常简单的方法,它也很快,但是会导致非常丑陋且冗长的网址。

这是这样做的方法

2.混淆的网址

这意味着,我们将文件公开供S3读取,但是所有文件都存储在难以猜测的命名文件夹中,例如:24fa0b8ef0ebb6e99c64be8092d3ede20000。但是,也许这不是最安全的方法。即使您永远无法猜测文件夹名称,在知道它之后(因为您实际上可以访问它),也可以与任何人(与任何未经授权的人)共享该链接。

3.通过我们的服务器下载文件

这意味着文件不是由S3直接提供的,而是首先由我们的服务器安全地读取并提供。我们真的不想要这个:)

4.检查引荐来源

混淆后的URL的解决方案可以用“确保”的要求来自于我们的服务器(你可以设置S3检查引荐)得到改善。但是,这将是一个非常不可靠的解决方案,因为并非所有浏览器都会发送引荐来源网址数据,而且该数据也可能是伪造的。

为不同客户端安全地从Amazon S3提供文件的一种好方法是什么?


1
您为什么在乎丑陋的长网址?您不是要让用户键入它,是吗?
ceejayoz

我真的相信这些网址是用户体验的一部分,而且我们不想让他们太长时间和丑陋:)
陶巴氏

2
我会说,在这种情况下,安全性和稳定性应该胜过漂亮的URL。这些不是博客文章的永久链接。
ceejayoz

Answers:


12

这确实与您“做我的系统架构”接壤,但是您的四个想法是有关可变安全性的有趣案例研究,因此让我们运行您的选项并看看它们的效果如何:


4.检查引荐来源

引荐来源网址由客户端提供。信任客户端提供的身份验证/授权数据会大大削弱安全性(我可以声称已从您希望我来自的位置发送邮件)。
判决: TERRIBAD的想法-微不足道。


3.通过我们的服务器下载文件

只要您愿意花费带宽来实现它,而且服务器是可靠的,这不是一个坏主意。
假设您已经解决了普通服务器/应用程序的安全性问题,那么这是您所提出的选项中最安全的一种。
结论:好的解决方案。非常安全,但如果带宽是一个因素,则可能次优。


2.混淆的网址

通过隐秘获得安全?真?不。
我什至不去分析它。就是不行。
结论:如果#4是TERRIBAD,那就是TERRIWORSE,因为人们甚至不必费力地伪造引荐来源标头。猜猜字符串并赢取所有数据奖励


1.使用PHP生成(过期)签名的URL

此选项的吸商很低。
任何人都可以单击URL并封杀数据,这是不安全的操作,但是您可以通过使链接过期(只要链接寿命足够短,漏洞窗口很小)来缓解这种情况。
URL过期可能会给某些想长时间挂在下载链接上的用户或不及时获取链接的用户带来不便-这对用户体验来说有点麻烦,但这可能是值得的。
结论:不如#3好,但是如果带宽是一个主要问题,它肯定比#4或#2好。


我该怎么办?

给定这些选项,我将使用#3 -通过您自己的前端服务器传递文件,并验证您的应用正常运行的方式。假设您的常规安全性相当不错,那么从安全性角度来看,这是最佳选择。
是的,这意味着您的服务器上将更多地使用带宽,并且更多的资源用于中间商,但是您始终可以为此多收取一点费用。


这是非常有用的分析,对此我非常感谢。#3的另一个大好处是-因为文件的url永不更改-我们可以大量使用浏览器缓存。再次感谢您的宝贵时间。
陶巴氏

@TamasPap无疑是#3的优势-优势有多大取决于您可以配置缓存的积极程度(以及人们从“新”计算机访问这些文件的频率)。
voretaq7


0

还有另一种方法。

您可以将AWS CloudFront指向S3存储桶,并使用签名Cookie将内容安全地提供给最终用户。

最终用户需要登录您的服务器以获取签名Cookie,然后在访问任何文件时将其发送到CDN。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.