安全上传

对于完全私有的论坛(不允许匿名访问),默认本地存储配置中缺乏安全的媒体选项,在我看来似乎是一个巨大的疏忽。如果许多运营私有论坛的用户没有意识到他们所有的帖子附件都是公开可访问的(只要知道 URL),我并不感到意外。如果我的帖子正文无法被匿名访问,直观上我会认为帖子附件也不应被匿名访问。

提交一个请求该功能的议题以了解能获得何种支持是否值得?是否已有相关议题?目前,这一问题是我们要在已拥有自有托管硬件、且不愿为云存储付费(尤其是 AWS S3 的价格)的环境中部署 Discourse 时无法接受的关键障碍。

另外,请原谅我这个问题可能显得天真。但目前已经支持为上传和备份使用不同的存储桶,对吗?为安全上传支持第三个存储桶是否困难?公开上传的文件放入公开存储桶,安全上传的文件放入安全存储桶,这样就不需要为每个对象单独设置 ACL。如果对象的 security 状态发生变化,只需将其在存储桶之间移动即可?

5 个赞

我认为这相当费工,至少需要一天,甚至可能是一周?

Cdck 托管服务(其开发费用由我们承担)将上传内容存储在 S3 上,因此只有那些无需 S3 预算、仅需登录即可自托管的站点才会感兴趣。

如果你的用户看到了你资源的分享链接,他们完全可以下载这些资源并自行分享。这似乎并不是一个大问题。

3 个赞

我觉得认为“帖子文本受保护但附件不受保护”很奇怪,这不算我脑子不清醒吧?

不过,有意分享和无意分享之间有着巨大的区别。显然,我们无法真正阻止前者。但后者目前就可能发生,仅仅因为人们不理解底层技术。例如,包含附件图片链接的帖子邮件通知可能会被无意中转发给非成员。提供一个与“安全媒体”功能解绑的选项,用于在邮件中抹除附件内容,或许是个不错的替代方案。

即使人们有意分享附件链接,他们也可能只是忘记了该链接来自受保护的分类。但在理想情况下,对于没有该分类访问权限的人来说,附件链接应该毫无价值。

此外,当前或未来的某个 S3 实现中的漏洞,也可能导致匿名用户枚举存储桶中的资源,或者能够猜测并暴力破解对象 URL。在理想世界中,我希望我的本地 S3 接口能被防火墙隔离,不直接暴露在互联网上,只有 Discourse 服务器能够直接访问它。

4 个赞

一点都不离谱。为非 S3 环境实现安全上传功能,我绝对不反对开发。只是目前我们并没有紧迫的需求或动力去构建这个功能,而且这项改动并非轻而易举。

我们偶尔会招募实习生或开展试做项目,这类任务完全可以归入其中一类。

14 个赞

对于在非 AWS S3 存储上实现安全媒体内容的更简便路径,您认为这种方案的可行性如何?

1 个赞

我有一个快速的小技巧,我认为可以为需要登录的网站提供安全的上传功能。

基本上,你可以按照 Authentication Based on Subrequest Result | NGINX Documentation 的说明为上传功能配置子请求认证。唯一的问题是,我无法找到一个在开启“需要登录”时返回 403/401 状态的 URL,因此未登录时访问上传链接会返回 500 错误。这种情况只会发生在有人获得了上传 URL 却在未登录状态下尝试访问时,所以看起来问题并不严重。

实现方式大致如下:

# JP
    location = /auth {
        internal;
        proxy_pass http://discourse/categories;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    } 
    # END JP
    location ~ ^/uploads/ {

      auth_request /auth; #$JP
      # 注意:我们无法在顶层定义头信息并继承,这确实很烦人。
      #
2 个赞

我们目前没有计划为安全上传开发独立的存储桶功能,也没有计划让安全上传在非 S3 环境或无 ACL 的环境中运行。如果未来对此类功能的需求达到一定程度,使我们认为值得投入时间和资源,我们可能会考虑开展相关工作。

5 个赞

为什么它使用的是 https://hashhackersforum.s3.us-east-2.amazonaws.com/optimized/2X/3/3204e85df407adfce19e105308248aee8b3b3f57_2_690x424.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAU5WBGG5Z7FNHQEIS%2F20210415%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20210415T025617Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=15c9118929ccd9c24a9594ab02a47e900269b9d921d41679a317e29d6174c2bc
而不是 https://forum.cdn.hashhackers.com/optimized/2X/3/3204e85df407adfce19e105308248aee8b3b3f57_2_690x424.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAU5WBGG5Z7FNHQEIS%2F20210415%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20210415T025617Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=15c9118929ccd9c24a9594ab02a47e900269b9d921d41679a317e29d6174c2bc

尽管我已经正确输入了 CDN 网址。

如果您启用了“安全媒体上传”,则不会使用 CDN。

5 个赞

我注意到管理员部分有一个警告:

服务器已配置为将文件上传至 S3,但未配置 S3 CDN。这可能导致高昂的 S3 费用并降低网站性能。点击此处了解“使用对象存储进行上传”的更多信息

我不介意忽略此提示,但我们已启用安全媒体(secure_media),这意味着无法使用 CDN。因此,在启用了 secure_media 的网站上,不应显示此消息。

1 个赞

您仍然可以为所有 JS 资源使用 CDN,这将大大加快全球用户的页面渲染速度。

3 个赞

这很酷。我之前没意识到 Discourse 会对静态资源进行特殊处理。我想我需要重新阅读这里的所有帖子。

2 个赞

升级至 2.8.0.beta1 版本后,我使用经过认证的 S3 URL 的 徽章 无法正常工作。升级前一切正常。

我检查了 uploads 表,其中 secure 列的值为 true

即使使用 新建徽章 选项上传文件,图片预览仍保持为空。

目前其他使用 S3 URL 的文件没有出现问题。

有任何帮助吗?谢谢!:wink:

2 个赞

啊……又一个本不该标记为安全的上传被错误地标记为安全的地方。徽章不应被标记为安全,因为它们本质上是公开图片,就像头像、分类标志和其他类似内容一样。我需要修复这个问题,确保徽章图片不被标记为安全,并编写一个迁移脚本来修正那些已被错误标记为安全的记录。

我很惊讶这对你居然能正常工作,2.8.0 版本中的任何内容都不应影响此功能。

5 个赞

你好 @martin

感谢您的回复。这是我第一次使用 Ruby,我很高兴发现这门语言如此清晰。经过几个小时的调试,我认为我已经找到了问题的关键。我想我正好做了与您所说的相反的操作 :slight_smile: 我在 Badge 模型中添加了一些代码,现在它可以加载图片了。我还注意到那里有一个 for_site_setting 标志。我相信它是依靠这个信息来调整 S3 上对象的 ACL,并将该列设置为 false。

app/models/badge.rb

  def image_url
    if image_upload_id.present?
      return upload_cdn_path(image_upload.url) if !image_upload.url.include?(SiteSetting.Upload.absolute_base_url)
      uri = URI.parse(image_upload.url)
      Rails.application.routes.url_for(
        controller: "uploads",
        action: "show_secure",
        path: uri.path[1..-1],
        only_path: true
      )
    end
  end

我将查看下一次升级会有哪些变化,以了解更多相关信息。
您能告诉我生产环境中最佳使用的版本是什么吗?

谢谢!

希望未来我能更多地为代码库做出贡献。

6 个赞

@danilogit

你对徽章模型所做的修改肯定能行得通,而且你第一次使用 Ruby 就能完成这项工作,这太棒了!不过,我仍然会着手修复核心问题,即徽章不应被标记为安全。

我们的 tests-passed 分支是生产环境的最佳选择,因为它会在修复可用时立即获取所有最新修复。不过,有些人可能更倾向于停留在 beta 分支,该分支大约每隔几周就会获取修复和变更。

一旦我完成了关于徽章被错误标记为安全的修复,我会通知你。

5 个赞

我今天完成了针对此问题的修复:

cc @danilogit

8 个赞

我刚发布了这条消息:

……但想知道该问题是否与你在评论中提到的内容有关?

在启用安全媒体上传的情况下,是否支持用户上传头像?目前我遇到了一个错误,但不确定这是否是因为头像被上传到了不允许公共访问的同一个存储桶中?

1 个赞

3 篇帖子已拆分为新主题:我能否同时在 Discourse 中使用安全媒体和页面发布?

我最近将“安全媒体”及相关设置重命名为“安全上传”,因为它不仅适用于图片/视频等,而且大家通常也称之为安全上传。相关的核心提交在这里:

此主题的原始帖子现已更新以反映这一点。

6 个赞