Repository navigation
fix(policy,catalog): enforce canonical base64url signatures, strict decimal bundle versions, and duplicate-key rejection (#802) - #807
Conversation
|
🟡 Contributor Check: MEDIUM
Automated check by AgenTrust Contributor Check. |
…ecimal bundle versions, and duplicate-key rejection (agentrust-io#802) - Enforce canonical unpadded base64url in policy.bundle._b64url_decode and catalog.approval._decode. - Require ASCII decimal segments in parse_bundle_version and reject duplicate JSON keys and NaN/Infinity in load_policy_bundle and PolicySigningKeys.apply_file. Closes agentrust-io#802 Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
e5ce67a to
0e42f82
Compare
carloshvp
left a comment
There was a problem hiding this comment.
Reviewed exact head 0e42f829620840e6bf79898f393f87e25b8f7bbc in an isolated checkout.
Requesting changes for a bounded validation finding in the changed security-sensitive path. I submitted the reproducer and a comparison against the actual merge-base behavior through the repository's private vulnerability-reporting channel, following SECURITY.md. Maintainers can find report GHSA-w5v5-4fgp-26x2; it is in triage and unpublished. Please address that report before this head is approved. This is a pre-merge regression report; I have not established released-version impact or additional attacker capability.
Separately, the ordinary local checks pass: 2,532 unit tests passed, 20 skipped in a hash-locked Python 3.12.10 environment; pip check, Ruff, mypy and Bandit passed. All commits have sign-offs. Those passing checks do not cover the privately reported control. git diff --check also flags an extra blank line at test_policy_bundle.py EOF.
Reviewed with OpenAI Codex.
noah-ing
left a comment
There was a problem hiding this comment.
Reviewed exact head 0e42f829620840e6bf79898f393f87e25b8f7bbc. My independent signed before/after replay confirms the validation regression already reported to maintainers through the private security channel. Requesting changes until that finding is fixed and covered by a targeted regression test; please coordinate the reproducer privately with the maintainers. I am keeping its mechanics out of this public review.
The ordinary exact-head unit suite passed (2,532 passed, 20 skipped), but it does not exercise the reported case. I saw no substantive hosted CI result for this head; the maintainer gate remains outstanding. This review does not assert released-version impact.
…ment in apply_file Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Thanks @carloshvp and @noah-ing! Fixed the pre-merge regression in |
|
Thanks for the update. I reviewed exact head One narrow strict-JSON case remains. |
Signed-off-by: Srinivasa Consultants <78673153+dinakarjs@users.noreply.github.com>
dinakarjs
left a comment
There was a problem hiding this comment.
I prepared a signed adoption companion addressing the outstanding review finding: dinakarjs#7
Validation: source repair unit suite 2547 passed/6 skipped; conformance+integration+confinement 114 passed/23 skipped. Final test-only parameterization rerun: all 37 policy-bundle tests pass. Its four nested-array cases each fail by assertion when the source repair is removed, with test names retained. Ruff src/tests, strict mypy and Bandit passed. No claim of authorization escalation: this closes strict-JSON acceptance.
Please cherry-pick/adopt the companion and request independent re-review of the resulting head. I have contributed the follow-up and am not approving my own contribution.
|
Thanks @noah-ing! Added |
|
Thanks @dinakarjs and @noah-ing! Adopted @dinakarjs's signed companion commit |
17a2d5b to
6546592
Compare
noah-ing
left a comment
There was a problem hiding this comment.
Reviewed exact head 654659216ece77f4e47bc78eb98aca703b8849f4. The signed revocation-row regression and nested invalid-JSON case from my prior review now behave correctly in independent before/after controls: an invalid row is rejected without suppressing the later valid signed row. The focused policy-bundle tests passed (37/37); the full unit suite passed (2,536 passed, 20 skipped), and Ruff, changed-source mypy, dependency and whitespace checks passed. This resolves my requested changes, so I approve this scoped patch.
Nonblocking issue tracking: #802’s summary also names _approval_schema, whose static bundled schema loader still uses permissive JSON parsing. I found no authority effect from that path. Please track it separately or adjust the Closes #802 reference before merge so it is not lost when the issue closes. Substantive hosted CI still needs to run under the normal gate.
carloshvp
left a comment
There was a problem hiding this comment.
Reviewed exact head 654659216ece77f4e47bc78eb98aca703b8849f4 in an isolated checkout.
My previous pre-merge validation finding is addressed by the adopted repair at this head. I independently replayed the privately reported case against both the previously reviewed source and the current source, with valid signed controls and rejection controls. The current implementation passes those controls while preserving rejection of an ambiguous signed statement. Details of the originally reported case remain in unpublished report GHSA-w5v5-4fgp-26x2; this public review omits the reproducer.
In a fresh hash-locked Python 3.12.10 environment, the full unit suite passed: 2,536 passed, 20 skipped. pip check, Ruff, mypy and configured Bandit also passed; the unit run used the loopback permissions needed by its local transport fixtures. Commit sign-offs are present. This supersedes my earlier code changes request at the older head. The private report remains unpublished/in triage, and required security-maintainer approvals, hosted CI and any advisory/release disposition remain separate. No released-version impact is asserted by this review.
Reviewed with OpenAI Codex.
|
Private-report follow-up at unchanged head The report remains in triage because GitHub returned HTTP 403 when I tried to record its resolved pre-merge disposition: this account lacks the security-advisory triage permission. An authorized repository security triager should disposition that private report using the repair evidence. This is not a claim about a released affected version. The PR still needs its normal merge/CI gates. I also changed the description to Reviewed with OpenAI Codex. |
What
Enforce canonical unpadded base64url in
cmcp_runtime.policy.bundle._b64url_decodeandcmcp_runtime.catalog.approval._decode, require strict ASCII decimal segments inparse_bundle_version, and reject duplicate JSON keys andNaN/Infinityin policy bundle manifests and revocation files.Why
Refs #802. The static bundled
_approval_schemaJSON loader remains tracked there as a separate follow-up.Security impact
Prevents malleable Ed25519 signatures (non-zero unused low padding bits) in policy bundles, key revocations, and catalog-approval records, prevents negative or non-ASCII integers in
parse_bundle_version, and blocks duplicate-key JSON smuggling inmanifest.jsonandsigning-key-revocations.json.Test plan
pytestpasses (pytest tests/unit/test_policy_bundle.py tests/unit/test_policy_signing.py tests/unit/test_policy_key_revocation.py tests/unit/test_catalog_approval.py -q)ruff checkpasses (ruff check src/cmcp_runtime/policy/bundle.py src/cmcp_runtime/catalog/approval.py tests/unit/test_policy_bundle.py)mypypasses (mypy src/cmcp_runtime/policy/bundle.py src/cmcp_runtime/catalog/approval.py)DCO sign-off
Developer Certificate of Origin (https://developercertificate.org).