Repository navigation
fix(conformance): catch RecursionError/TypeError and walk tuples in canonical_claim_bytes (#517) - #518
Open
drk-ram wants to merge 2 commits into
Conversation
…anonical_claim_bytes - Catch RecursionError and TypeError from json.dumps in trace_tests.inclusion.canonical_claim_bytes and raise InclusionError so tr_anc.check reports a TR-ANC-002 FAIL finding instead of escaping runner.run when a receipt is supplied (agentrust-io#517). - Walk tuple alongside list in trace_tests.inclusion._outside_profile so tuples carrying floats or out-of-range integers cannot bypass the anchor-leaf profile check. - Include tr_apr and appraisal.status in test_modules_never_raise and exercise tr_anc.check with a well-formed receipt across field mutations and deep/non-JSON/tuple claims. Closes agentrust-io#517 Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…thon 3.12+ In Python 3.12+ on Linux, C-extension json.dumps checks the C stack via _PyOS_CheckStack rather than sys.getrecursionlimit(), so depth 2000 does not trigger RecursionError. Use depth 100_000 (matching test_untrusted_input_hardening.py). Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This branch has not been deployed
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.
What this changes
Closes #517.
In
conformance/src/trace_tests/inclusion.py:canonical_claim_bytespreviously calledjson.dumps(claim, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode("ascii")without catchingRecursionErrororTypeError. Although_outside_profilewalks the claim iteratively ("because the claim is attacker-controlled and may be deep"),json.dumpsis recursive and raised an unhandledRecursionErroron deeply nested claims (orTypeErroron non-JSON-serializable values), escapingtr_anc.checkand crashingrunner.runwhen a receipt was supplied.canonical_claim_bytesnow catchesRecursionErrorandTypeErrorand raisesInclusionError("claim nests too deeply to serialize")andInclusionError(f"claim contains a value that is not JSON serializable: {exc}")respectively (matchingsrc/agentrust_trace/sign.py:anchor_bytes), sotr_anc.checkreports aTR-ANC-002Status.FAILfinding instead of raising._outside_profilepreviously descended only intodictandlist, allowing atuplecontaining a float or out-of-range integer (such as{"a": (1.5,)}or{"a": (2**53,)}) to bypass_outside_profileand serialize as a JSON array viajson.dumps._outside_profilenow descends into(list, tuple).In
conformance/tests/test_modules_never_raise.pyandconformance/tests/unit/test_tr_anc.py:tr_aprtoMODULESand(("appraisal", "status"), "TR-APR-001")toNESTED_DISCRIMINANTSinconformance/tests/test_modules_never_raise.pyso all eight conformance modules and their nested discriminator fields are swept.test_tr_anc_with_receipt_never_raises_on_malformed_or_deep_recordsinconformance/tests/test_modules_never_raise.pysotr_anc.checkis exercised with a well-formed receipt across all field mutations as well as deeply nested, non-JSON, and tuple-wrapped claims.conformance/tests/unit/test_tr_anc.pyforcanonical_claim_bytesandtr_anc.checkon deeply nested claims, non-JSON values, and tuples carrying floats or unsafe integers.Cold-reader review:
A cold review of the initial diff against
conformance/src/trace_tests/modules/tr_apr.pyfound thattr_apr.py:167-169comments# in against a frozenset raises on an unhashable value, and a record is not trusted to carry a hashable one; test_modules_never_raise fuzzes this field with a list, but addingtr_aprtoMODULESalone only fuzzed top-levelrecord["appraisal"](which returns early atif not isinstance(appraisal, dict)) and never mutatedrecord["appraisal"]["status"]because("appraisal", "status")was absent fromNESTED_DISCRIMINANTS. Added(("appraisal", "status"), "TR-APR-001")toNESTED_DISCRIMINANTS(and"appraisal"totest_runner_fails_nested_discriminators_instead_of_raising) soappraisal.statusis fuzzed with lists, objects, and allJUNKvalues astr_apr.pydocuments.Contributor: Raghuvar Durga (@drk-ram)
Type of change
Spec section
None (conformance test suite fix in
conformance/src/trace_tests/inclusion.py,conformance/tests/test_modules_never_raise.py, andconformance/tests/unit/test_tr_anc.py).Tests for a fix
Deeply nested claim (
RecursionError->InclusionError/TR-ANC-002Status.FAIL):conformance/tests/unit/test_tr_anc.py::test_deeply_nested_claim_raises_inclusion_error_and_fails_tr_anc_002(fails withRecursionError: maximum recursion depth exceeded while encoding a JSON objectwhen theexcept RecursionError:handler incanonical_claim_bytesis switched off):Non-JSON-serializable value (
TypeError->InclusionError/TR-ANC-002Status.FAIL):conformance/tests/unit/test_tr_anc.py::test_non_json_serializable_claim_raises_inclusion_error_and_fails_tr_anc_002(fails withTypeError: Object of type object is not JSON serializablewhen theexcept TypeError as exc:handler incanonical_claim_bytesis switched off):Tuple containing a float or out-of-range integer (
_outside_profilewalking(list, tuple)):conformance/tests/unit/test_tr_anc.py::test_tuple_outside_anchor_profile_raises_inclusion_error_and_fails_tr_anc_002(fails withFailed: DID NOT RAISE <class 'trace_tests.inclusion.InclusionError'>whenisinstance(v, (list, tuple))in_outside_profileis reverted toisinstance(v, list)):Validation Commands Run
python tools/check_dashes.py: passed (no dashes outside examples/, spec/trace-v0.1.md)python -m ruff check src tests scripts conformance/src/trace_tests/inclusion.py conformance/tests/test_modules_never_raise.py conformance/tests/unit/test_tr_anc.py: passed (All checks passed!)python -m mypy src/agentrust_trace conformance/src/trace_tests/inclusion.py: passed (Success: no issues found in 16 source files)python -m pytest conformance/tests/test_modules_never_raise.py conformance/tests/unit/test_tr_anc.py conformance/tests/test_tr_anc_inclusion.py -v: passed (63 passed)Push-Location conformance; python -m pytest tests -q; Pop-Location: passed (726 passed, 5 xpassed)python -m pytest tests/test_conformance_import_style.py -v: passed (2 passed)Checklist
git commit -s)CHANGELOG.mdupdated (for any normative change)<!-- CHANGED: #NNN: description -->in spec text