【问题标题】:Rails implementation for securing S3 documents用于保护 S3 文档的 Rails 实现
【发布时间】:2011-06-18 22:02:13
【问题描述】:

我想通过 rails 应用程序保护我的 s3 文档,这样如果我去:

www.myapp.com/attachment/5 应该在显示/下载文档之前对用户进行身份验证。

我已经阅读过关于 stackoverflow 的类似问题,但我不确定我是否看到了任何好的结论。

根据我的阅读,您可以采取多种措施来“保护”您的 S3 文档。

1) 混淆 URL。我已经做到了。我认为这是一件好事,所以没有人能猜出 URL。例如,如果您的 S3 URL 很明显:https://s3.amazonaws.com/myapp.com/attachments/1/document.doc,则很容易“遍历”该 URL。有一个 URL,例如: https://s3.amazonaws.com/myapp.com/7ca/6ab/c9d/db2/727/f14/document.doc 似乎好多了。 这样做很好,但不能解决通过电子邮件或网站传递 URL 的问题。

2) 使用如下所示的过期 URL:Rails 3, paperclip + S3 - Howto Store for an Instance and Protect Access 然而,对我来说,这不是一个很好的解决方案,因为 URL 是公开的(即使只是很短的时间),另一个用户可能会及时快速地重用 URL。您必须调整时间以允许下载,而不会为复制提供太多时间。这似乎是错误的解决方案。

3) 通过应用代理文件下载。起初我尝试只使用 send_file:http://www.therailsway.com/2009/2/22/file-downloads-done-right 但问题是这些文件只能是您服务器上的静态/本地文件,不能通过其他站点 (S3/AWS) 提供。但是,我可以使用 send_data 并将文档加载到我的应用程序中,然后立即将文档提供给用户。这个解决方案的问题很明显 - 两倍的带宽和两倍的时间(将文档加载到我的应用程序然后返回给用户)。

我正在寻找一种解决方案,它可以提供#3 的完全安全性,但不需要额外的带宽和时间来加载。看起来 Basecamp 正在他们的应用程序背后“保护”文档(通过身份验证),我认为其他网站也在做类似的事情,但我认为他们没有使用我的 #3 解决方案。

我们将不胜感激。

更新

我选择了第四个解决方案:

4) 使用亚马逊存储桶策略来控制对基于引用者的文件的访问: http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?UsingBucketPolicies.html

再次更新:

#4 可以通过浏览器开发人员的工具轻松解决。所以我仍在寻找可靠的解决方案。

【问题讨论】:

    标签: ruby-on-rails security amazon-s3 obfuscation


    【解决方案1】:

    你想做两件事:

    1. 将存储桶和其中的所有对象设为私有。命名约定实际上并不重要,越简单越好。

    2. 生成签名 URL,并从您的应用程序重定向到它们。这样,您的应用程序可以检查用户是否经过身份验证和授权,然后生成新的签名 URL 并使用 301 HTTP 状态代码将其重定向到该 URL。这意味着文件永远不会通过您的服务器,因此您没有负载或带宽。以下是签署 GET_OBJECT 请求的文档:

    https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Presigner.html

    【讨论】:

      【解决方案2】:

      我会投票给 3,这是唯一真正安全的方法。因为一旦您将用户传递给在其到期时间之前有效的 S3 URL。狡猾的用户可能会利用这个漏洞,唯一的问题是,这会影响您的应用程序吗? 也许您可以将过期时间设置得更低,从而将风险降至最低? 看一下这篇文章的摘录: Accessing private objects from a browser

      所有私有对象都可以通过 对 S3 的经过身份验证的 GET 请求 服务器。您可以生成一个 对象的经过身份验证的 url,例如 这个:

      S3Object.url_for('beluga_baby.jpg', 'marcel_molina')
      

      默认情况下 经过身份验证的 URL 过期 5 分钟 生成后。

      可以指定过期选项 要么有一个绝对的时间,因为 带有 :expires 选项的纪元,或 相对于秒数 现在使用 :expires_in 选项:

      【讨论】:

      • 感谢您的帖子。这不是我的#2 解决方案吗?我知道它是可行的,但它似乎不是一种真正安全的方法。出于某种原因,我觉得它留下了一个洞(即使它很小)。关于如何在没有双带宽问题的情况下实施我的 #3 的任何建议?
      • 它尽可能地接近安全。您可能可以使用某种反向代理来获取此信息,但带宽将在某处使用。我只需将超时设置为 1 分钟。
      • 我希望我错过了一些与某些 apache 插件相关的解决方案,它可以基于来自 RoR 的身份验证进行重定向。超时(无论您尝试设置的窗口有多小)是否仍然允许某种程度的不安全感?....但是我同意这可能只是唯一的两个答案。如果没有其他人插话,我会将您的设置为正确答案。谢谢。
      • 是的,但即使使用重定向,用户也会被发送到 S3 url。如果您不重定向,那么您正在将位从 S3 移动到您的服务器,然后再到用户。
      【解决方案3】:

      很长一段时间以来,我一直在尝试做类似的事情。如果您不想两次使用带宽,那么唯一可行的方法就是允许 S3 这样做。现在我完全同意你公开的 URL。你能想出任何替代方案吗?

      我发现了一些在这方面可能有用的东西 - http://docs.aws.amazon.com/AmazonS3/latest/dev/AuthUsingTempFederationTokenRuby.html

      用户登录后,应创建一个将其 IP 作为 aws 策略一部分的 aws 会话,然后可用于生成签名 URL。因此,如果其他人抓取了签名将不匹配的 URL,因为请求的来源将是不同的 IP。让我知道这是否有意义并且足够安全。

      【讨论】:

        猜你喜欢
        • 2021-04-28
        • 2017-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-23
        • 1970-01-01
        • 2010-09-25
        相关资源
        最近更新 更多