Skip to content

fix(verify/nv_certify): enforce strict JSON, exact int version, validated base64, and lowercase hex in verify_gateway_measurement (#810) - #815

Open
drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-nv-certify-810
Open

drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-nv-certify-810

Conversation

@drk-ram

@drk-ram drk-ram commented Oct 25, 2026 •

Copy link
Copy Markdown

What

Enforce duplicate-key and non-finite JSON rejection, exact int version (type(version) is int), base64.b64decode(..., validate=True), and lowercase hex gateway_digest in verify_gateway_measurement, and validate type(index) is int and isinstance(written, bool) in measurement_nv_public_bytes.

Why

Closes #810.

Security impact

Prevents duplicate-key JSON smuggling, boolean/float version coercion ("v": true or 1.9), non-base64 character injection in NV certify envelopes, and non-canonical uppercase/whitespace hex in gateway_digest.

Test plan

  • pytest passes (pytest tests/unit/test_nv_certify.py tests/unit/test_nv_policy.py -q: 78 passed)
  • ruff check passes (All checks passed!)
  • mypy passes
  • Manual test performed

DCO sign-off

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Oct 25, 2026

@noah-ing noah-ing left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tightening the NV envelope. I reviewed head b687f7d: 74 focused tests and the full unit suite (2,538 passed, 20 skipped) passed, and independent signed controls confirm the main malformed-input cases fail closed. Two narrow parts of #810 remain:

  1. gateway_digest is checked for lowercase, nonempty, even-length hex, but not the issue's required 64-character length. A fully signed 62- or 66-character value passes envelope validation and fails only at the later digest comparison. Please require exactly 64 characters and add negative tests.
  2. parse_constant catches literal NaN/Infinity, but JSON exponent overflow such as 1e1000 is parsed as Python infinity. Adding that value in an ignored field to an otherwise valid signed envelope still returns verified=True. Please reject non-finite floats throughout the parsed envelope and add a regression, including a nested field.

Neither case bypasses signature or NV policy. They do leave the strict envelope contract incomplete, so I am requesting these focused changes before #810 closes.

@carloshvp carloshvp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head b687f7d011e3d9ac6a0c0e16361aad30256eca52 in an isolated checkout.

I independently confirmed the two remaining envelope-contract gaps identified in the current-head review:

  1. A valid signed positive control still returns verified=True after adding an ignored top-level or nested JSON field with the numeric token 1e1000. parse_constant rejects literal NaN, but exponent overflow becomes a non-finite float without invoking that hook. Please reject non-finite decoded numbers recursively, with top-level and nested regression cases.
  2. gateway_digest accepts 62- and 66-character strings at the envelope-validation stage. Both are later refused by the digest comparison, but the required fixed 64-character SHA-256 envelope check is missing. Please enforce that length before decoding and test both sides of the boundary.

The intact signed control passes, and literal NaN is rejected as malformed_envelope. These observations establish the strict-input contract gaps; they do not establish a signature or NV-policy bypass. The ordinary exact-head suite passes (2,538 passed, 20 skipped), as do pip check, Ruff, mypy, configured Bandit, sign-offs and diff whitespace checks. Requesting the focused changes above before approval.

Reviewed with OpenAI Codex.

@drk-ram

drk-ram commented Oct 29, 2026

Copy link
Copy Markdown
Author

Thank you @noah-ing and @carloshvp! Addressed both points in 7992792 (rebased onto origin/main at 6cf01bb):

  1. Exact 64-character gateway_digest check at envelope validation:
    • Required len(gw_hex) == 64 alongside lowercase hex validation in verify_gateway_measurement, and added signed negative tests for 62- and 66-character gateway_digest strings asserting failure_reason == "malformed_envelope" and "envelope" not in result.verified_fields.
  2. Exponent-overflow float rejection (parse_float=_parse_float):
    • Added _parse_float checking math.isfinite(val) to json.loads so JSON exponent overflow (1e1000, -1e1000), including inside nested ignored fields ({"extra": {"nested": [-1e1000]}}), fails closed with malformed_envelope.

@drk-ram
drk-ram force-pushed the drk-ram-fix-nv-certify-810 branch from b687f7d to 7992792 Compare October 29, 2026 15:26

@noah-ing noah-ing left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused follow-up at head 799279204fe258c553db0763426993146139a369. The two source gaps in my earlier review are addressed: the envelope now requires a 64-character lowercase gateway_digest, and exponent-overflow numbers, including nested ones, are rejected. Signed positive and malformed controls passed; I found no signature or NV-policy bypass.

One committed test still needs to follow the corrected contract. test_non_sha256_length_claimed_gateway_digest_is_rejected expects gateway_digest_mismatch for a 31-byte claimed digest. The new envelope check correctly returns malformed_envelope before that value can be verified. On this exact head, the focused suite had 77 passed and 1 failed; the full unit suite had 2,550 passed, 20 skipped, and this same 1 failure. The 10 NV reference integration tests passed.

Please update that assertion to malformed_envelope, assert that "envelope" is absent from verified_fields, and rerun the suite. A local test-only correction of those lines made the unit and NV reference suites pass (2,561 passed, 20 skipped); it is not part of this head. Please also refresh the PR description's older 74 passed test claim after the rerun. The fork's substantive hosted workflows are awaiting authorization, so I am not claiming a hosted CI pass.

…ated base64, and 64-char hex in verify_gateway_measurement (agentrust-io#810)

Reject duplicate JSON keys, literal and overflow non-finite numbers
(via parse_constant and parse_float), non-int envelope version, invalid
base64 strings, and non-64-character or non-lowercase gateway_digest hex
at the envelope boundary in cmcp_verify.nv_certify, and validate types
in measurement_nv_public_bytes.

Closes agentrust-io#810

Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
@drk-ram
drk-ram force-pushed the drk-ram-fix-nv-certify-810 branch from 7992792 to 48c3721 Compare October 29, 2026 20:28
@drk-ram

drk-ram commented Oct 29, 2026

Copy link
Copy Markdown
Author

@noah-ing Updated test_non_sha256_length_claimed_gateway_digest_is_rejected in 48c3721 to assert result.failure_reason == 'malformed_envelope' and 'envelope' not in result.verified_fields, reran pytest tests/unit/test_nv_certify.py (78 passed), and updated the PR description.

This branch has not been deployed

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

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk

Projects

None yet

3 participants