security: prepare v5.0.1 Django replay protection hotfix - #3871
Conversation
Signed-off-by: Jeff Stock <jstock@microsoft.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Carlos Hernandez (carloshvp)
left a comment
There was a problem hiding this comment.
I reviewed head f1a7a8e8 against target c57d9d9a, which is the v5.0.0 commit. I compared the security code with merged #3782, built and installed the core wheel in a clean environment, and ran all 44 Django middleware tests from the installed artifact. I also exercised request tampering and replay concurrency. Changes to the method, path, query, body, content type, timestamp, nonce, or signature returned 403. A reused nonce returned 403, and one of 32 concurrent copies passed. The replay defense behaves as intended.
The release artifact still has a blocking version mismatch:
METADATA: 5.0.1
agentmesh.__version__: 5.0.0
agent_os.__version__: 5.0.0
agent_runtime.__version__: 5.0.0
hypervisor.__version__: 5.0.0
The four __init__.py files say their constants must stay in sync with package metadata, and the core wheel bundles all four namespaces. python scripts/sync-version.py --check reports success because the script does not inspect these constants. Please bump the four runtime versions to 5.0.1 and extend the version check or artifact test to cover them. A scanner or application that reads __version__ would classify the patched wheel as vulnerable 5.0.0 while importlib.metadata reports 5.0.1.
The changelog and release notes also state a release date of 2026-09-01. As of 2026-09-03, GitHub has no v5.0.1 tag or release and PyPI still serves 5.0.0. Please set the date at publication or use an unreleased placeholder until then.
After those release-integrity fixes, I have no security finding in the replay implementation.
Imran Siddique (imran-siddique)
left a comment
There was a problem hiding this comment.
The release topology is sound and I verified it rather than taking it on trust. There is one finding
that I think has to be resolved before this ships, and it is the kind that only shows up if you diff
the release tree against main rather than against the PR it backports.
Verified, all of it:
- The base branch
liamcrumm/esrp-ame-glibc235-publishpoints atc57d9d9a4849556a3c5347d359012d7a85bc3dfb, which is exactly what tagv5.0.0resolves to. So "the exact public v5.0.0 source" is literally true, and building the patch off that branch really does isolate it from unreleasedmainwork. - #3782 ("fix: prevent replay attacks in Django trust middleware") is merged, 2026-08-19.
Validate PR titleshows red in the rollup but there is a SUCCESS 2 minutes 27 seconds later on the same head. That entry is stale, not a real failure.
The finding: this backports #3782 and stops there, but the same middleware was hardened again
afterwards.
#3813 ("fix: enforce signed http trust verification") merged to main on 2026-08-25, six days
after #3782 and a week before this PR was opened. It is tagged as a Security fix and it references a
published advisory, GHSA-5j58-vjjg-pcgm.
The diff shows the gap plainly. Against current main, this branch's middleware is behind:
middleware.py 47 added / 174 removed
request_auth.py 30 added / 12 removed
test_django_middleware.py 40 added / 100 removed
And the shared module #3813 introduced is absent entirely:
agent-governance-python/agent-mesh/src/agentmesh/integrations/request_auth.py
main -> present
this PR -> does not exist
which is why this branch's middleware.py drops the RequestTargetMode, decoded_target,
select_signed_headers and wsgi_raw_target imports, along with replay_key and
_VERIFIED_TRUST_SCORE.
So as it stands, v5.0.1 would ship a Django trust middleware that fixes the replay issue and does
not carry the fix for the advisory that followed it. Anyone who takes v5.0.1 because it is the
security patch release would be getting one of the two security fixes on that component, which is the
worst possible outcome for a release whose entire purpose is to be the safe thing to upgrade to.
What I would do. Backport #3813 onto this branch as well, and cover both in
docs/releases/RELEASE_NOTES_v5.0.1.md, the advisory text and the upgrade notes. If for some reason
#3813 is deliberately out of scope, that needs saying explicitly in the release notes, because a
patch release that silently omits a fix with a published GHSA is worse than no patch release.
The rest of the PR is in good shape. Preparing an isolated tree from the exact tag rather than
cherry-picking onto main is the right call, the fail-closed compatibility break is stated plainly
rather than buried, and offering the maintainers a protected release/5.0 branch at v5.0.0 as an
alternative target is the right way to raise a topology question you cannot resolve yourself.
One smaller note: this branch is 182 commits behind main, which is expected and correct given
it is deliberately cut at v5.0.0. Flagging it only so nobody reads the drift as staleness and
rebases it onto main, which would defeat the whole point.
|
MohammadHaroonAbuomar liamcrumm this needs a maintainer decision before it ships, not just a The release topology checks out: the base branch points at exactly the So |
Summary
v5.0.1security patch from the exact publicv5.0.0source5.0.1and add changelog, advisory, upgrade, and release documentationRelease topology
This PR targets
liamcrumm/esrp-ame-glibc235-publishbecause that canonical branch points to the exact same commit as tagv5.0.0. This keeps the hotfix isolated from unrelated unreleased work onmain. A maintainer can create a protectedrelease/5.0branch atv5.0.0and retarget this PR before merge if preferred.The implementation is already present on
mainthrough #3782. This PR prepares the independently reviewable patch-release tree and metadata.Security behavior
The prior middleware authenticated only the agent DID, so an observed valid request could be replayed and unsigned request components could be changed. The fixed protocol binds the audience, timestamp, nonce, method, path and query, content type, and body digest into the Ed25519 signature. Verified nonces are claimed atomically and retained through the signature-validity window.
This is an intentional fail-closed compatibility change. DID-only signatures are rejected. Production servers must configure
AGENTMESH_AUDIENCEand a shared Redis or memcached replay cache.Validation
agent_governance_toolkit_core-5.0.1-py3-none-any.whlbuilds successfully5.0.1site-packagesPublication gates
After approval:
Publish Packagesforagent-governance-toolkit-corewithdry_run: trueand inspectrelease-manifest.json, signatures, provenance, and the wheel contents.v5.0.1tag and GitHub Release from the approved hotfix commit.No internal incident identifiers or unassigned vulnerability identifiers are included in this PR.