Discourse Assign - 导致网站崩溃的漏洞

我最近更改了允许使用 Discourse Assign 的群组设置。点击更新按钮后,出现严重错误,导致整个站点瘫痪。

此后我已禁用 Discourse Assign,站点已恢复运行,但无法再次启用该插件。一旦重新启用,站点就会再次瘫痪,且无法更改 Discourse Assign 插件的站点设置。

我查看了错误日志,发现两条错误信息:

ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR:  invalid input syntax for integer: "patently-staff"
LINE 1: ...RE "group_users"."user_id" = 1 AND (groups.id in ('patently-...
                                                             ^
: SELECT  1 AS one FROM "groups" INNER JOIN "group_users" ON "groups"."id" = "group_users"."group_id" WHERE "group_users"."user_id" = 1 AND (groups.id in ('patently-staff')) LIMIT 1)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:69:in `async_exec_params'

以及:

Failed to handle exception in exception app middleware : PG::InvalidTextRepresentation: ERROR:  invalid input syntax for integer: "patently-staff"
LINE 1: ...RE "group_users"."user_id" = 1 AND (groups.id in ('patently-...
                                                             ^
: SELECT  1 AS one FROM "groups" INNER JOIN "group_users" ON "groups"."id" = "group_users"."group_id" WHERE "group_users"."user_id" = 1 AND (groups.id in ('patently-staff')) LIMIT 1

您实例中的 discourse-assign 插件是否为最新版本?或者您是否曾在之前分叉过该插件?discourse-assign 插件在 7 月曾进行了一项 变更,该变更似乎与您遇到的错误相关。

2 个赞

你好,Penar,我很确定它已经是最新版本了,我定期更新所有内容,包括插件。

我想我不得不进行恢复了,最后的备份是在我更改那个站点设置之前进行的。

你好 @jerry0

根据日志显示,该插件已是最新版本。请问你正在运行哪个版本的 Discourse?

2 个赞

最新版本,当前为 2.4.0.beta4

嗯,我明白了。您是在更新到 beta4 之前还是之后更改的设置?

看起来我们的自动迁移未能成功更新您的设置,我将调查原因。在启用插件之前,您是否尝试过重启服务器,以防旧值可能被缓存?如果这不起作用,请告诉我,我会为您提供一个 Ruby 脚本来手动修复此问题。

1 个赞

谢谢 @Roman

这发生在我更新之前。当我添加新设置时,出现了一些奇怪的情况,我想我可能在“添加”新组名之前就点击了绿色的勾选按钮。

我不太清楚如何操作(顺便提一下,我在原始帖子中说“禁用/启用”时可能表述有误——我的意思是我在 app.yml 文件中注释掉了 git clone 的 URL 以添加插件)。当我在 yml 文件中添加该插件时,网站会立即崩溃(而它之前是启用的),所以我无法进入后再将其设置为禁用……除非我误解了您的意思?

这很可能有必要,我们将不胜感激。

如果不介意的话,我想在手动修改设置之前再验证一件事。

您能否在 Rails 控制台中执行以下代码,并告诉我输出结果?

DB.query_single(<<~SQL
  SELECT site_settings.value FROM site_settings WHERE site_settings.name = 'assign_allowed_on_groups'
SQL
).first.to_s.split('|')

这将告诉我们该设置的值是否迁移失败。

访问控制台的方法:

  • cd 进入您的 Discourse 文件夹
  • 进入容器运行 ./launcher enter app
  • 运行 rails c 打开 Rails 控制台
3 个赞

响应为

=> [“patently-staff”]

1 个赞

谢谢,Jerry。

这里确实有些问题。我会检查一下,看看为什么会发生这种情况。

脚本如下:


group_id = Group.where(name: 'patently-staff').pluck(:id).join('|')

DB.exec("UPDATE site_settings SET value='#{group_id}' WHERE site_settings.name = 'assign_allowed_on_groups'")

运行后,你应该可以重新启用该插件。

7 个赞

太好了,成功了 :grin: 谢谢 @Roman。如果有任何我可以提供的协助,请随时告知。

1 个赞

你好,Roman,

我们在将 Discourse 升级到 2.4.0beta4 后,使用 discourse-assign 插件时也遇到了类似的问题。

该问题仅出现在通过 LDAP 登录的用户身上。(我们使用 “GitHub - jonmbake/discourse-ldap-auth: Discourse plugin to enable LDAP/Active Directory authentication. · GitHub” 进行 LDAP 连接)

DB.query 的响应为:
=> [“staff”]
但 “Group.where(name: ‘staff’).pluck(:id).join(‘|’)” 返回的是空字符串 “”。

顺便提一下:在版本 “2.4.0.beta1 +203” 中,响应结果类似,但通过 LDAP 登录是可行的。(LDAP 版本 0.4.0,assign 插件版本 0.1)

任何帮助都欢迎,
谢谢,
Frank

你好 @diwr

根据该查询,您没有名为 staff 的组。也许您将其重命名为其他名称?

您可以通过执行以下命令来确认:Group.where(id: 3).pluck(:name)

我认为如果 staff 组已被重命名,该迁移将无法正常工作。我今天会查看一下这个问题。

2 个赞

谢谢 @Roman

看来它已被重命名为“团队”。
现在该怎么办?

您可以使用“team”作为组名来运行该脚本。

4 个赞

@Roman
非常感谢。
在设置该值后,我不得不运行 “./launcher rebuild app”,但随后它就正常工作了。

6 个赞