Skip to content

fix(verify): enforce canonical base64url and reject private JWK members in kill_switch and claim verification #804

Open

Description

@drk-ram

Summary

Two verification boundary gaps exist in src/cmcp_verify/kill_switch.py and src/cmcp_verify/verify.py:

  1. Non-canonical base64url keys/signatures and missing string checks in verify_kill_switch_refusal (src/cmcp_verify/kill_switch.py lines 36-95):

    • _b64url_decode in kill_switch.py calls base64.urlsafe_b64decode(value + "=" * (-len(value) % 4)) without checking ^[A-Za-z0-9_-]+$, len(value) % 4 != 1, or round-trip canonical encoding (base64.urlsafe_b64encode(raw).rstrip(b"=").decode("ascii") == value), accepting malleable refusal receipt signatures and keys.
    • verify_kill_switch_refusal does not verify that receipt["agent_id"], receipt["session_id"], and receipt["refused_at"] are non-empty strings (isinstance(..., str) and value).
  2. Private JWK members and non-canonical base64url accepted in cmcp_verify.verify (src/cmcp_verify/verify.py lines 183-295):

    • _verify_signature, _verify_key_binding, and _jwk_x_to_hex in src/cmcp_verify/verify.py do not reject RFC 7517/7518/8037 private or symmetric JWK parameters (d, p, q, dp, dq, qi, oth, k) on claim["trace"]["cnf"]["jwk"], and decode trace.cnf.jwk.x and claim["signature"] without enforcing canonical unpadded base64url (^[A-Za-z0-9_-]+$, len % 4 != 1, round-trip match).

Proposed Fix

  • Enforce canonical unpadded base64url in cmcp_verify.kill_switch._b64url_decode and cmcp_verify.verify (_verify_signature, _verify_key_binding, _jwk_x_to_hex), and require non-empty string agent_id, session_id, and refused_at on kill-switch refusal receipts.
  • Reject private/symmetric JWK members (d, p, q, dp, dq, qi, oth, k) on trace.cnf.jwk in cmcp_verify.verify.

Activity

  1. github-actions commented on Oct 23, 2026

    @github-actions
    Contributor

    🟡 Contributor Check: MEDIUM

    Check Result
    Profile MEDIUM
    Credential LOW
    Overall MEDIUM

    Automated check by AgenTrust Contributor Check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions