Enabled plugins are trusted by NAME, so a session can swap the module behind one
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Bắt đầu với plugins/trust.py, plugins/loader.py và registry._construct, sau đó đọc các tham chiếu đến config_digest trong PR #495 và ngữ cảnh liên quan trong #461. Một maintainer phải lựa chọn giữa việc từ chối các shadow có nguồn gốc từ project và pin nội dung triển khai; công việc được xem là hoàn tất khi một tên plugin được bật không thể khiến các byte của module không đáng tin cậy được thực thi, với các test bao phủ trust model đã chọn.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Python
- Star
- 165
- Fork
- 69
- Merge trung bình
- 1 ngày 5 phút
- Pull request đã merge (30 ngày)
- 86
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của bmad-code-org/bmad-loop
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 69/100
bmad-code-org/bmad-loop#973 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
bmad-code-org/bmad-loop#965 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 72/100
bmad-code-org/bmad-loop#1004 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 49/100
bmad-code-org/bmad-loop#1002 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
tickets: an injected plan_halt result for a built plan escalates with stopped-attempt wordingĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 36/100
bmad-code-org/bmad-loop#972 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của bmad-code-org/bmad-loop
Issue tương tự
-
[oblt-aw][autodoc] Document new required `shared-org-key` input for `obs-aw-dependency-review`Có thể đã có người làm @github-actions đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
Maintainer thường phản hồi trong vòng 1 ngày
-
getchaintips leaves out the active tip once a header is staged on it, where Core always lists itĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
btclib-org/btclib-node#2158 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
dbt-msft/dbt-sqlserver#897 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Gathin23/cleanyourtv#2770 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Dao-AILab/flash-attention#3097 ·
Maintainer thường phản hồi trong vòng 3 ngày