Evidence record / agent-zero

A dated record of one change, kept so the writing that cites it can be checked. Compiled from the sources listed below by the research run, not written for reading. The judgment lives in the signals and issues that cite it, below.

2026-08-17-agent-zero-ssrf-fix-for-cve-2026-4308-was-silently-lost-in-a-plugin-refactor-and

SSRF fix for CVE-2026-4308 was silently lost in a plugin refactor and shipped broken through 11 stable releases before v2.9 restored it.

Receipt b40874e7c03775c53989e206769e33ff23a4384e resolves (2026-08-12T02:18:35Z). Message: "Fix document query SSRF regression / Route remote document downloads through the existing public-only HTTP fetcher so direct and redirected non-public destinations are rejected... Add focused CVE-2026-4308 regression coverage for private targets and genuine public-fetch compatibility." Two files touched: plugins/_document_query/helpers/fetch.py and tests/test_document_query_plugin.py. The diff is exactly as described: -import aiohttp / +from helpers.network import fetch_public_http_resource, replacing async with aiohttp.ClientSession(...) as session: async with session.get(uri, allow_redirects=True) with await asyncio.to_thread(fetch_public_http_resource, uri, max_bytes=..., timeout=...).

Corroboration I gathered independently:

  • Original patch 6397acc092a538594186c6a2bacdcfa516ca0747, 2026-04-12, "Fix SSRF in document_query remote fetching (CVE-2026-4308)", touching helpers/document_query.py + helpers/network.py. helpers/network.py at v2.8 still contains validate_public_http_url() with blocked = [str(ip) for ip in ips if not ip.is_global] and fetch_public_http_resource() -- the guard existed and was simply not called.
  • Regressing commit 6ccbae071228ee8146a62d402343f7bd67f5cf63, 2026-05-29, "feat(document_query): add liteparse runtime and progressive skill", which created the plugin and its own fetch.py.
  • gh api commits?path=plugins/_document_query/helpers/fetch.py returns exactly two commits ever: 6ccbae0712 (introduce) and b40874e7c0 (fix). Exposure is continuous, never partially remediated.
  • Raw file check at v1.19, v2.0, v2.4, v2.8: all four carry import aiohttp and session.get(uri, allow_redirects=True) at the same line numbers. helpers/document_query.py at v2.8 is a pure shim ("""Compatibility shim for the document_query plugin extraction.""") re-exporting from plugins._document_query, so the unguarded path was the live path, not dead code.
  • v2.9 release notes, under "Fixes": "SSRF regression in document queries (CVE-2026-4308): remote document downloads now route through the public-only HTTP fetcher, rejecting private targets including through redirects." One line, vendor's only disclosure.
  • repos/agent0ai/agent-zero/security-advisories returns []. Global advisory GHSA-8g9j-3hrr-2hvm, type "unreviewed", severity medium, CVSS3 6.3, published 2026-03-17.
  • NVD CVE-2026-4308: published 2026-03-17T04:16:24, CVSS 4.0 base 2.1 LOW with exploitMaturity PROOF_OF_CONCEPT, PR:L; "The exploit has been made available to the public... The vendor was contacted early about this disclosure but did not respond in any way."

WHERE IT BREAKS: the headline count. Affected non-prerelease tags are v1.19, v1.20, v2.0, v2.1, v2.2, v2.3, v2.4, v2.5, v2.6, v2.7, v2.8 -- eleven, not thirteen. Both the releases API and the tags API agree there is nothing between v1.20 (2026-06-04) and v2.0 (2026-06-24), which is where the missing two would have to live. Thirteen is only reachable by counting v1.18 (pre-regression, clean) and v2.9 (the fix) into the broken window.

Channel: tagged-release. Ancestry: gh api repos/agent0ai/agent-zero/compare/b40874e7c0...v2.9 -> status=ahead, ahead=9, behind=0, so the fix commit is an ancestor of the stable (non-prerelease) tag v2.9. Exposure boundary established the same way: gh api compare/6ccbae0712...v1.18 -> status=behind (not contained); compare/6ccbae0712...v1.19 -> status=ahead behind=0; compare/6ccbae0712...v2.8 -> status=ahead behind=0. So the regressing commit is in v1.19 through v2.8 and the fix lands only in v2.9. All tags checked are non-prerelease per the releases API (prerelease=false).

Operator consequence: Upgrade to v2.9 if you run document query against untrusted or user-supplied URLs. Every stable release from v1.19 (2026-06-02) through v2.8 (2026-08-01) -- eleven tags -- shipped plugins/_document_query/helpers/fetch.py calling aiohttp directly with allow_redirects=True and no public-only guard, while helpers/network.py sat right there in the same tree still exporting the fetch_public_http_resource that the April patch had added. NVD rates it CVSS 4.0 2.1 with a public proof of concept and PR:L, so this is a privileged-user pivot into your internal network, not an unauthenticated one; scope your urgency accordingly, but do not dismiss it if operator access is broadly shared.

Then re-audit rather than assume. The failure mode is not a missing fix, it is a fix that was present, tested, and discarded when a refactor moved the call site into a plugin -- commit 6ccbae0712 on 2026-05-29, which touched fetch.py exactly once and was not touched again until the repair. If you carry local patches or vendored forks across Agent Zero's plugin-extraction churn, diff your security-relevant call sites against helpers/network.py instead of trusting that a CVE you already patched is still patched.

And note the notification gap: the repo's security-advisories endpoint is empty, the only GitHub advisory (GHSA-8g9j-3hrr-2hvm) is an unreviewed NVD import that predates the regression by two months and describes the original 0.9.7 bug, and the vendor's sole disclosure of the regression is one bullet under "Fixes" in the v2.9 release notes. Nothing in your dependency tooling will tell you this happened.

Correction note: an earlier draft of this finding overstated the evidence. It was refuted in the run's adversarial receipt pass before publication and the wording above is the corrected form. See qa.md in this run for what was wrong.

Receipt

Finding metadata

Run: 2026-08-17-weekly-digest-2026-08-10_2026-08-17-frontier-v0

Finding ID: 2026-08-17-agent-zero-ssrf-fix-for-cve-2026-4308-was-silently-lost-in-a-plugin-refactor-and

Source links

Primary links, including exact changelog lines when available.

Versioned source: run artifact