fix(security): reject all-zero Ed25519 registry key and verify hook script integrity#3901
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…eholder (#3799) The official registry Ed25519 public key constant was an all-zero 32-byte placeholder. The code detected this (`is_placeholder`) but silently skipped verification instead of rejecting the operation. An all-zero key is a valid Ed25519 key whose private key is trivially known, so any attacker can sign arbitrary payloads for it — skipping is indistinguishable from no security. Both call sites now return a hard error when the placeholder is active: - `fetch_verified_index`: refuses to download/use the registry index - `install_from_registry`: refuses to install the plugin archive Three unit tests pin the behaviour: - `official_registry_pubkey_is_placeholder_all_zeros` — constant decodes to zeros - `is_placeholder_detects_built_in_constant` — gate correctly flags the constant - `is_placeholder_passes_real_key` — gate does not false-positive on a real key Operators who need to bypass verification for development can still set `LIBREFANG_REGISTRY_VERIFY=0` / `LIBREFANG_ARCHIVE_VERIFY=0`.
…#3804) The checksum verification in `install_from_registry` only covered the manifest (`plugin.toml`), not the hook scripts it references. An attacker who controls the download path can serve a legitimate manifest with a valid checksum while substituting arbitrary Python/Node/shell hook scripts that execute under the daemon's privileges. The fix adds a post-install check: after the manifest and archive signature are accepted, every hook script path declared in `[hooks]` must have a corresponding entry in `[integrity]`. A missing entry causes the install to fail and the partial installation to be cleaned up. The `[integrity]` section already existed in `PluginManifest` and was enforced by `load_plugin_manifest` at load time, but was never required at install time — meaning a plugin with no integrity entries could be installed from the registry without any hook-file verification. Four unit tests pin the detection logic: - `hook_integrity_no_hooks_no_requirement` — no hooks → no entries required - `hook_integrity_missing_entries_detected` — partial coverage is flagged - `hook_integrity_all_covered_passes` — full coverage passes - `hook_integrity_all_hook_fields_checked` — all seven hook fields are inspected Operators who need to install unverified plugins during development can use `PluginSource::Local` or `PluginSource::Git` which do not go through the registry install path.
houko
force-pushed
the
worktree-agent-a3f6daeb297524bab
branch
from
April 28, 2026 14:11
9930b3a to
8005ed9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#3799 — Plugin registry public key is all-zero placeholder
OFFICIAL_REGISTRY_PUBKEY_B64was a 32-byte zero placeholder. Bothfetch_verified_indexandinstall_from_registrysilently skipped verification whenis_placeholderwas true. Now both return a hardErr— installs are blocked until a real key is configured. Escape hatch viaLIBREFANG_REGISTRY_VERIFY=0/LIBREFANG_ARCHIVE_VERIFY=0for operators who need to opt out.New tests:
official_registry_pubkey_is_placeholder_all_zeros,is_placeholder_detects_built_in_constant,is_placeholder_passes_real_key#3804 — Hook scripts not checksummed (only plugin.toml was)
After archive signature passes, the installed
plugin.tomlis re-parsed and every hook declared in[hooks]is checked against the[integrity]map. Any declared hook without an integrity entry causes the install to be rolled back (target dir removed).All 7 hook fields checked:
ingest,after_turn,bootstrap,assemble,compact,prepare_subagent,merge_subagent.New tests: 4 covering no-hooks, partial coverage, full coverage, all fields.
Fixes
Test plan