Skip to content

Fix: Bound POST /verify (JSON) body size and field cardinality - #407

Open
rajnisht7 wants to merge 1 commit into
agentrust-io:mainfrom
rajnisht7:fix-bound-json-verify-body
Open

Fix: Bound POST /verify (JSON) body size and field cardinality#407
rajnisht7 wants to merge 1 commit into
agentrust-io:mainfrom
rajnisht7:fix-bound-json-verify-body

Conversation

@rajnisht7

Copy link
Copy Markdown
Contributor

What

Adds the same body-size and collection-cardinality limits to POST /verify (JSON) that POST /verify/cose already has.

Why

POST /verify took a VerifyRequest Pydantic model directly, so FastAPI would fully buffer and validate an arbitrarily large JSON body e.g. a trusted_keys dict with millions of entries before any verification logic ran. POST /verify/cose already guards against this; this endpoint didn't.

Closes #383.

Spec impact

None

Test plan

  • pytest -v passes
  • mypy src/agent_manifest passes
  • ruff check src/ tests/ passes
  • New or updated tests cover the change
  • If spec change: CHANGELOG.md updated

DCO

All commits in this PR are signed off (git commit -s). By submitting this PR I certify the Developer Certificate of Origin.

@rajnisht7
rajnisht7 requested review from a team, carloshvp and zohebk8s as code owners September 8, 2026 11:56
@rajnisht7

rajnisht7 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

The failing test (test_followup_tutorial[operations/monitoring.md-expected0]) is unrelated to this PR it's a pre-existing dependency-lock issue.

prometheus-client is declared in pyproject.toml's dev extra but was missing from requirements/dev.in requirements/dev.txt.

Opened a PR for the same #408

Signed-off-by: rajnisht7 <rajnishtiwari9787@gmail.com>

@imran-siddique imran-siddique 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.

Approving. Three of the things in this PR were not asked for and each of them is the reason to take it rather than a bonus on top.

The seventh field. The report named six. verified_attestation_manifest_hashes has the identical unbounded set[str] shape, sits directly below two fields that were named, and reaches VerificationContext by the same path. Capping six and leaving the seventh open would have moved the attack rather than closed it, and your comment says exactly that in the code where the next reader needs it. Fixing the instances the reporter missed is the right instinct on a bounds defect, because the bound is only worth what its weakest field is.

The regression you caught in your own change. Swapping a VerifyRequest parameter for a raw Request removes FastAPI's automatic Content-Type gate, so the route would have parsed a JSON body submitted as text/plain, as a bogus subtype, or with no header at all, contradicting the application/json contract its own OpenAPI schema advertises. That is invisible in a diff review: the removed behaviour has no line in the patch. Restoring it explicitly with FastAPI's own rule (application/json, a +json vendor subtype, or absent) rather than a stricter homemade one is the right call, because a stricter gate would have been a silent behaviour change for existing callers.

The pre-existing bug you found looking for the first one. Both routes checked the accumulated buffer against the cap after appending each chunk, so the buffer could be grown a full chunk past the limit before rejection. Checking before appending is correct and it fixes verify_cose, which was not in scope. A size cap enforced after the allocation is not a size cap.

The 1 MiB byte cap and the 10,000-entry collection cap answer different attacks and both are needed: the byte cap alone misses a small body carrying a million short keys, and the entry cap alone misses one enormous value. Renaming MAX_COSE_ENVELOPE_BYTES to the endpoint-neutral MAX_VERIFY_BODY_BYTES and sharing it across both routes keeps them from drifting apart again, which is how this gap opened in the first place.

On CI: every one of the ten failing lines across the five platform jobs is test_docs_first_manifest.py::test_followup_tutorial[operations/monitoring.md] failing on ModuleNotFoundError: No module named 'prometheus_client'. That is #408, your other PR, now merged, and it was failing on main and on every open PR in this repository. Nothing in your diff caused a failure. I am closing and reopening this so CI recomputes against a main that has the lockfile fix, since a re-run would replay the original merge commit and keep the stale base.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

POST /verify (JSON) has no body-size or field-cardinality cap, unlike the COSE /verify endpoint

2 participants