Enabled plugins are trusted by NAME, so a session can swap the module behind one
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
先从 plugins/trust.py、plugins/loader.py 和 registry._construct 开始,然后阅读 PR #495 中对 config_digest 的引用以及 #461 中的相关上下文。维护者必须在拒绝项目来源的 shadow 和固定实现内容之间做出选择;完成的标准是,启用的插件名称不能导致不受信任的模块字节被执行,并且测试覆盖所选的信任模型。
由索引模型根据 Issue 内容生成。
描述
Split out of #461 point 4 / PR #495, where the config-integrity pin closes the config half of this but not the implementation half. Found by an automated reviewer on that PR and confirmed against the code.
The hole
trust.require_enabled gates in-process Python on the plugin name only:
def require_enabled(policy, name) -> None:
if not is_enabled(policy, name):
raise PluginUntrusted(...)
and plugins/loader.py discovery is an overlay whose highest precedence source is inside the agent-writable workspace:
builtin (bmad_loop.data/plugins/*) lowest
entry_point (inert today)
project (<project>/.bmad-loop/plugins/*) highest — same-name override
registry._construct then resolves Path(manifest.scripts_dir) / manifest.python.module and calls spec.loader.exec_module(module). For a project-origin manifest, scripts_dir is <project>/.bmad-loop/plugins/<name>/.
So given a project whose policy already has [plugins] enabled = ["tea"], a driven session can write .bmad-loop/plugins/tea/plugin.toml + its own module, and the next registry build imports and executes that module in the orchestrator process. The name never changed, so the allowlist is satisfied. The simpler variant needs no builtin to shadow: if enabled names a plugin that does not exist yet, the session just creates the directory.
Unlike the ungated-declarative-shell-hooks item (also out of scope on #495), this one is inside the trust tier that is supposed to be gated — plugins/trust.py's own docstring says a [python] plugin is "never imported or executed unless its name is in [plugins] enabled", and that is true of the name while saying nothing about the bytes.
Why PR #495 does not close it
#495's runsetup.config_digest hashes sorted(policy.plugins.enabled). That catches a session adding a name to the allowlist. It cannot catch a session changing what an already-allowlisted name resolves to, because no policy field moves. The gap is recorded in the config_digest docstring and the CHANGELOG entry so the pin is not read as stronger than it is.
Shape of a fix (undecided — needs a maintainer call)
Two directions, and this is a plugin-trust-model decision rather than a hashing one, which is why it is not folded into #495:
- Refuse the shadow. Reject a project-origin manifest whose name collides with a builtin, or refuse project-origin
[python]plugins entirely and require in-process plugins to be installed outside the workspace. Cheapest and closest to the relay fix in #461 points 1-3 (move the executable surface out of the agent-writable tree), but it is a behavior change for anyone developing a plugin in-tree. - Pin the implementation. Extend the trust record to a content digest of the manifest + the
[python]module, established when the operator enables the plugin. Preserves in-tree development but needs a place to store the pin and an--acceptpath when the operator legitimately edits their own plugin. Watch for false positives if a plugin writes into its own{scripts}dir.
Either way the auto-sweep gate then inherits the guarantee for free, since it already refuses on a moved config digest.
Notes
- Default
[plugins] enabledis empty, so a stock project is unaffected. The exposure is limited to projects that have deliberately enabled a[python]plugin. - This is not a regression: it predates #495, which narrows the surrounding surface without widening this one.
Related: #461, PR #495.
- 主要语言
- Python
- 星标
- 165
- 派生
- 69
- 平均合并
- 23 小时 42 分钟
- 30 天内合并 PR
- 87
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
bmad-code-org/bmad-loop 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 69/100
bmad-code-org/bmad-loop#973 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
bmad-code-org/bmad-loop#965 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 72/100
bmad-code-org/bmad-loop#1004 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 49/100
bmad-code-org/bmad-loop#1002 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 36/100
bmad-code-org/bmad-loop#972 ·
维护者通常 1 天内回复
查看 bmad-code-org/bmad-loop 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
namespace operations
难度 1/5 1 小时以内 新手友好度 65/100
EclipseFdn/open-vsx.org#15057 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
FinanceFlash/unvibecode#349 ·
-
Mission statement: why this is free, in the README, Why This Exists and the wiki Home可能已有人在做 @ChiefGyk3D 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 76/100
ChiefGyk3D/Clouds-Against-Humanity#348 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
vllm-project/vime#508 ·
维护者通常 4 天内回复