使用 PostgreSQL 插件时的权限问题和 auth 插件的安全性以及论坛界面问题

  • 使用 postgresql 数据库插件时,我新建了一个叫“koishi“的用户并创建了一个名为“koishi“的数据库,然后给了这个用户 “koishi“ 数据库和 SCHEMA public 全部权限

    GRANT ALL PRIVILEGES ON DATABASE koishi TO koishi;
    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO koishi;
    

    仍然报错 app PostgresError: permission denied for schema public

    然后给 koishi 用户变更为 SUPERUSER 应用才正常运行。

    但是这样做是不安全的,因为 SUPERUSER 拥有数据库的所有权限。

    万一 koishi 被植入恶意代码,所有数据库都有被破坏的风险。

    可能因为我是数据库新手,不知道除了这两个还需要哪些权限,希望可以在教程中写明需要的权限,并引导用户为了数据库安全仅赋予必要的权限,避免只有 SUPERUSER 才可使用 koishi 的数据库插件。

  • koishi 启动时报错有连接问题,但是插件市场其实是可以正常打开使用的,不知道这一大串日志是什么问题引起的

  • 刚刚遇到的,还是使用 postgresql 数据库插件,我在插件 apply 开头尝试
    ctx.database.drop('一个不存在的表'),然后 koishi web 控制台就卡了,我刷新页面之后,账户被登出了(使用了 auth 插件)。

    我想登录,却怎么也登录不了,点登录按钮没反应,但是还是可以看到欢迎界面和依赖图。

    然后我就在服务器上重启 koishi,嗯,能正常登录进去了,但是整个数据库被清空了,之前所有的数据都没了,重置到了一开始的状态,不清楚具体原因。

  • 即使启用了 auth 插件,没登录的外部用户仍然可以看到欢迎界面中的服务器相关信息和依赖图,我认为这不太安全,希望可以在未登录的情况下隐藏所有信息。

    上方弹出的红色警告信息也只有一个叉叉,没有任何文字信息。

    而且,直接在 url 栏中输入 /sandbox 也是可以直接进去的,还可以添加用户,不需要登录,不知道还有没有其他页面可以绕过 auth 插件直接进入。

  • 论坛里的主题当换成 Material Design Theme 时, 左下角切换主题的按钮会消失,只能在设置里更换,其他主题则没有这个问题。

    浏览器是 Edge,版本 121.0.2277.83 (正式版本) (64 位)

  • 在发帖的输入框中编辑时,按下"Tab"键焦点会直接跳到"+创建话题"按钮下, 无法在输入框中进行缩进。

    正在使用的主题是 Radiant


System:

OS: Linux 5.15 Ubuntu 22.04 LTS 22.04 (Jammy Jellyfish)

CPU: (4) x64 Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz

Binaries:

Node: 18.15.0

Yarn: 4.0.1

Koishi:

Core: 4.16.7

Console: 5.27.2

@koishijs/plugin-database-postgres 1.1.4 (可更新)
@koishijs/plugin-market 2.10.6 (可更新)
@koishijs/plugin-auth 4.1.6 (最新)

4 个赞

3 个赞

3 个赞

3 个赞

感谢反馈!问题比较多,我会在接下来的几天内一一回应。

希望可以在教程中写明需要的权限,并引导用户为了数据库安全仅赋予必要的权限

我不是特别了解 PostgreSQL,我已经帮你询问了熟悉这方面的人,正在等待回应。

koishi 启动时报错有连接问题,但是插件市场其实是可以正常打开使用的,不知道这一大串日志是什么问题引起的

请问你是直接使用 Koishi Desktop 或者模板项目启动的吗?有没有修改过 market 插件的配置?

ctx.database.drop('一个不存在的表')

听起来是 PostgreSQL 插件的 bug,我们会尽快查明原因。

即使启用了 auth 插件,没登录的外部用户仍然可以看到欢迎界面中的服务器相关信息和依赖图,我认为这不太安全,希望可以在未登录的情况下隐藏所有信息。

插件的作者可以选择自己的插件是否要对所有用户开放。碰巧这两个插件都没有设置权限,因此你可以在登出状态下看到信息。我们后续会更新这两个插件,允许用户手动设置为非登录状态不可见。

上方弹出的红色警告信息也只有一个叉叉,没有任何文字信息。

这应该是 bug。如果你能给出稳定的复现流程,将有助于我们修复此问题。

论坛里的主题当换成 Material Design Theme 时, 左下角切换主题的按钮会消失,只能在设置里更换,其他主题则没有这个问题。

这是一个非官方插件,你可以前往该插件的 GitHub 仓库提交 issue。

5 个赞

我这里也是一样。我不知道 discourse 是否支持输入框缩进功能。

5 个赞

可以,但需要先选中文本再点 tab

shift + tab 也是工作的

4 个赞

已发放等级

3 个赞

仍然报错 app PostgresError: permission denied for schema public

我也没有在实际生产中使用过postgres,不过根据我刚刚查询的结果,此处应当需要

GRANT ALL ON SCHEMA public TO koishi;

这会赋予当前所连接数据库的全部(create+usage)权限,而不会得到跨数据库的权限。而对ORM而言,拥有database内的完整权限是合理的。

这样后续第三点中数据库相关的问题应当不存在,如果有问题请再提出。

6 个赞

虽然这可能是一个 bug,但任何时候都不推荐 插件 使用数据库的 drop 功能。插件的行为会影响到每一个用户使用的实例,插件作者误用了此功能后可能会造成巨大的代价。

需要删除表的时候,推荐按照以下方法操作:

  1. 整个数据库 进行一次备份
  2. 使用专门的数据库管理软件进行删除操作

大多的附加主题是主题作者根据自己的需求和喜好进行布局的,这个主题的作者可能没有经常更换主题的需求,所以隐藏了这个选框。


这里确实可以改进一下。

4 个赞

是使用模板项目启动的,使用 ctx.http 时改过全局代理,使用全局代理时无法打开插件市场,然后就把全局代理配置项清空了,再之后插件市场就出现了这个问题 ,但是可以正常加载使用

今天早上又出现了新的问题


所有依赖无法获取版本,日志中也有好几屏(几十条 “[W] market connect ECONNREFUSED 127.0.0.1:80” 报错)

插件市场可以搜索到插件但是无法修改和添加

也许可以在 auth 插件中增加一个配置项, 不论原有插件是否开放, 均对外部用户不可见, 这个选项可以覆盖所有插件的可见性设置

我也不清楚这是怎么出现的了,到处折腾一下,有时手动增加了一些插件或者修改配置网页就会自动刷新。我现在重启浏览器之后再尝试登出登录,那个只有一个叉叉的提示神奇地消失了。

这样操作并移除 SUPERUSER 权限之后确实可以正常使用了,感谢。(但没有测试过从零开始是否有效)

建议在 database-postgres 插件的 usage 描述中增加对权限要求的描述, 并提醒用户不要直接使用数据库的 SUPERUSER 用户以增加数据库安全性。
确保积极响应 《Koishi 实例安全性公告 》文件的相关政策。

当时我在开发插件,已经 extend 了一个数据表,但是某个字段设计有问题想更改,直接更改字段名之后发现原有字段还残留在数据表中,我想着还没有数据就直接把整个表删除重新创建,然后就使用了这个 drop 方法。

当时的上下文是

export function apply(ctx: Context) {
  ctx.database.drop(‘一个不存在的表’);
  ctx.model.extend("...", { ... });
 }

ctx.database.drop 实际上是一个异步方法,但我当时没有注意到这一点,忘了加 await 关键字,不清楚这个问题是否和异步操作有关。

为什么会 drop 到一个不存在的表?因为有 hmr,我的字没打完就自动重载触发了这个语句。

然后就是不知怎么回事重启 koishi 之后 “koishi” 数据库就被重置了,对于开发者来说这是毁灭性的影响。如果使用了其他插件并存储了一些数据,那么这些数据都会消失。

首先建议 koishi 提高数据库插件自身的 Robustness 和安全性,不管插件开发者怎么折腾都不会把整个数据库重置;插件也许可以做更精细的权限控制,比如默认没有删除表的权限、只能删除由该插件声明的表等等。

其次是完善文档,如果 任何时候都不推荐 插件 使用数据库的 drop 功能,那么应该在 数据库操作 (Database) | Koishi 这个 api 旁边注明他的危险性以及可能的严重后果,增加一个类似插件市场中不安全插件的图标标识。

然后如果可能的话,再出一个数据库备份插件,因为数据无价。

2 个赞

从早上到现在,再去看发现又可以使用了。

但是重启 koishi 之后又不行了,难道又要等一段时间才能刷新出来?

:roll_eyes:

2 个赞

Koishi 的文档接受 PR,该项建议可以直接在文档底部点击”在 GitHub 编辑此页面“反馈修改~

不过我认为在 API 处标注不推荐使用有些欠妥。不推荐 drop 的原因出在设计层,而非 API 本身的行为上。该 API 行为稳定符合预期,清楚其功能后使用并不会产生不可控结果。或许在开发指南的数据库部分新增相关条目更合适。

2 个赞

我确认了源码,ctx.database.drop(‘一个不存在的表’); 不应该造成任何预期外的问题,我也无法复现你的问题。我现在倾向于认为在你hmr时实际上输入了空参数或空字符串作为参数,从而如预期地删除了全表。

至于在此处开发时使用drop,本质和使用外部数据库管理软件进行操作并无区别,这无可厚非。我们不推荐实际生产上的插件使用drop,因为这可能引发全局而不可控的副作用,破坏其他可能使用此表此列的插件的行为,而几乎不存在真正使用drop有意义的场景。而只要不使用drop,就无论如何不应该出现所述将整个数据库重置等对数据造成极大危害的情形。假如需要在版本更迭中进行数据表迁移,我们也有legacy和migrate。

5 个赞

这个反倒是不行的,一个框架最优先需要保证的是开发者的需求,虽然我们不推荐开发者 drop 掉整个数据库,但我们并不应该在代码里阻碍开发者这么做。而我们应当做的就是,在代码中提供这样的功能,但不建议开发者这样使用。


那确实应该是 hmr 导致了数据库 drop,这也是预期的行为。只要文件发生变动,hmr 就会重载新文件的逻辑。


个人认为 drop 操作及其后果应该由开发者学习数据库的过程中了解。作为对比,DataGrip 等世界一流数据库管理软件在 Drop 操作中也没有任何有关危险性的文字或颜色提示。如果需要这类功能的话,不如在进行危险操作的时候使用一个带有此类警告的软件。


插件市场十个月前应该已有开发者发布了这样的插件,并也在本论坛发帖。可以搜索一下。

3 个赞

谢谢大佬们的解答。

空参数时竟然会删除全部表吗?这个我没看到文档中有提到。

GPT 对此给出的回答是:

在 SQL ORM(Object-Relational Mapping,对象关系映射)框架中,drop 函数的行为可以依据具体的 ORM 框架和其版本有所不同。通常,ORM 框架提供了操作数据库的抽象,包括创建、查询、更新和删除数据库表的功能。

对于 drop 函数,它一般用于删除数据库中的表。如果你没有指定具体的表名作为参数,其行为取决于该函数在你使用的 ORM 框架中的具体实现:

  • 在一些 ORM 框架中,如果 drop 函数的参数为空,它可能不会执行任何操作,因为安全机制防止无意中删除所有表。
  • 在其他框架中,调用 drop 函数而不指定具体表名可能会导致一个错误或警告,提示需要明确指定要删除的表。
  • 极少数情况下,如果框架设计允许这种操作,调用 drop 函数而不指定参数可能会删除所有表,但这种设计非常危险,因为它可能导致数据丢失,所以大多数 ORM 框架都不会允许这样做。

我的本意不是想 drop 掉整个数据库,提供这个功能没问题,但不应那么容易地被触发到。特别是开启了 hmr 的情况,可能也有其他开发者刚打了个括号就重载触发 drop 掉了整个数据库。

hmr 是预期的行为,drop 空参数删除全表也是预期行为,但这两结合起来应该不是开发者想看到的。

DataGrip 是专业的数据库管理软件,开发者理应在了解数据库之后才使用它,它假设了开发者具备一定的专业知识。

而 Koishi 是一个聊天机器人框架,封装了很多应用层的东西,Koishi 用户的技术门槛较低,其他开发者可能跟我一样是数据库新手,这时给出必要的警告我觉得是合理的。

3 个赞

你描述的这种行为仅会在 hmr 启用+编辑器实时保存+drop代码在加载时触发 时出现。作为一个开发者,如果其开发环境设置了实时保存,本人应当对其影响有一定了解和预期。Koishi 无法对每个开发者的环境做出假设并一一对应,所以按照更主流的开发习惯默认启用了 hmr,并在开发指南内描述了其行为。我觉得这是比较合理的处理。如果为了取消某种编辑器设置和开发设置叠加导致的不希望产生的行为而修改框架代码或文档,似乎有点本末倒置。自行修改开发环境应该是更合理的处理。

update:

对此说得更有道理。


因为我前述的这种特殊情况出现的稀有性,在 Koishi 现有开发指南已经非常新人友好,而数据库相关接口的描述也非常清晰的前提下,没有这个警告的负面影响应该是非常有限的。不过我支持你向开发指南的数据库相关教程贡献这项警告~

2 个赞

你说得对。原来我们有dropAll,那无参数的drop确实应该是个错误(从类型检查上现在也确实是个错误)。我们会考虑从代码上阻止这一行为。

3 个赞

看了这些讨论,我觉得可以直接把 drop 从文档中删掉(

2 个赞

还有个场景,我的亲身经历。

在使用 hmr 和 ctx.model.extend 时,因为我的键入速度很慢,等我全部键入完成看一眼数据库时,发现了众多由子串组成的表 :sob:

1 个赞