Summary
CVE-2026-111764 tracks a fail-open default in the A2A Java SDK’s server-common package, org.a2aproject.sdk:a2a-java-sdk-server-common (Maven ecosystem). With the SDK’s default configuration, task reads are not authorized: any caller can retrieve a task created by another caller — including its status, context, message history, and artifacts — simply by supplying the task id. The issue is disclosed as GitHub advisory GHSA-qw47-mcm5-934w, scored 7.5 High with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, and mapped to CWE-862 (Missing Authorization), with CWE-1188 (Insecure Default Initialization) also cited by the advisory. The OSV ecosystem range marks every version before 1.3.0.Final as affected, and the fix is associated with the v1.3.0.Final release.
Technical Analysis
This is not a memory-safety or injection bug; it is a default-wiring decision that treats the absence of an authorization configuration as permission. Two independent defects combine in the task store component.
First, the default initialization is insecure. The advisory quotes the production code for InMemoryTaskStore:
public InMemoryTaskStore() {
this.authorizationProvider = null; // default wiring
}
@Override
public @Nullable Task get(String taskId) {
return tasks.get(taskId); // no owner / caller check
}
The no-argument constructor sets authorizationProvider = null. A missing provider is treated as allow-all rather than as a reason to deny access, so the shipped default is the unsafe posture and the safe posture is opt-in — the pattern CWE-1188 labels Insecure Default Initialization of Resource.
Second, the read path is entirely unguarded. InMemoryTaskStore.get(String taskId) is a bare map lookup with no owner or caller check — and, per the advisory, no authorization check runs on this path regardless of provider. Even an application that configures a TaskAuthorizationProvider does not make get() itself authorize; the check simply does not exist there.
Authorization is enforced only when an application both supplies a TaskAuthorizationProvider and routes requests through AuthorizationRequestHandlerDecorator (via CDI), which checks ownership before delegating. The advisory identifies three wiring paths that never reach that check:
- a server that uses the default store;
- a server that wires
DefaultRequestHandler.builder().build()manually; - a server that integrates through a non-CDI stack, with Spring given as an example.
The advisory’s remediation section makes the asymmetry explicit: it asks that the authorization check be applied in the store’s get path, not only in list and the CDI decorator, so the check holds regardless of how the handler is wired. In other words, some authorization exists elsewhere in the current code, but the path that returns a single task by id is unguarded.
The advisory’s remediation also names the correct posture outright: fail closed — deny task reads when no authorization provider is configured, rather than treating a missing provider as allow-all. The net result of the current design is a cross-caller read primitive: a caller can read a task created by another caller simply by knowing or guessing its id. Because the insecure behaviour is the default rather than a misconfiguration, the advisory stresses that it is easy to ship unintentionally.
Affected Software and Versions
- Ecosystem: Maven
- Package:
org.a2aproject.sdk:a2a-java-sdk-server-common— the task store / authorization component of the A2A Java SDK - Affected versions (advisory list):
<= 1.2.0.Final, plus1.2.1.Final-SNAPSHOTonmainprior to the fix - Affected range (OSV ecosystem data): introduced at version 0, fixed in
1.3.0.Final— that is, every version before 1.3.0.Final - Fixed in:
1.3.0.Final - Verified affected: the advisory’s proof of concept reproduces on
1.2.0.Finaland onmainat commit72d220c(JDK 21)
There is a small discrepancy worth noting between the two sources: the advisory’s affected list names <= 1.2.0.Final and the pre-fix snapshot, while the OSV range generalizes to all versions before 1.3.0.Final. For upgrade decisions, treat anything below 1.3.0.Final as affected. The vulnerability is not listed in CISA’s Known Exploited Vulnerabilities (KEV) catalog.
Impact
Impact is confidentiality-only, matching the C:H/I:N/A:N components of the CVSS vector: task data crosses caller boundaries with no authorization. In any multi-caller deployment built on the default wiring, one caller can enumerate and read another caller’s tasks. The advisory itemizes what a task carries: task status, context id, the message history, and any artifacts the task carries — which, for agent workloads, is frequently sensitive input and generated content.
Two properties make this worse than a typical misconfiguration finding:
- The insecure behaviour is the default. A team that never thinks about task authorization gets the permissive behaviour silently. The advisory describes this as easy to ship unintentionally.
- The default/reference deployment does not enforce transport authentication. Per the advisory, in the default/reference deployment the transport endpoints are served without authentication enforced, so the read is reachable by an unauthenticated caller. That is reflected in the CVSS vector as
PR:N(no privileges required),AC:L(low attack complexity), andAV:N(network attack vector).
The base score is 7.5 (High), and the advisory notes it is scored against the default configuration as shipped — not against a hardened deployment that has opted into authorization.
Exploitation Scenario
The following scenario is illustrative, constructed from the advisory’s description of the default wiring and the cross-caller read. It is not a claim about any specific deployment.
Imagine a multi-caller agent service built on the A2A Java SDK with default wiring — for instance, a team integrating the SDK into a Spring-based stack, which the advisory names as a non-CDI path that never reaches the authorization decorator. Caller A submits work to the service, and the resulting task — status, context id, message history, artifacts — lands in the default InMemoryTaskStore. For agent workloads, the advisory notes, that content is frequently sensitive input and generated output.
Caller B has no relationship with Caller A and no authorization context. Caller B supplies Caller A’s task id — known, guessed, or enumerated — and the store’s get path performs a bare map lookup. No ownership check runs, and Caller B receives Caller A’s task in full. Because the default/reference deployment serves its transport endpoints without authentication enforced, Caller B may not even need an account on the service.
The advisory’s own proof of concept compresses this to three steps against the real production classes, with no mocks:
- Construct the default store:
InMemoryTaskStore store = new InMemoryTaskStore();— the no-arg constructor, so no authorization provider. - As one caller, save a task:
store.save(victimTask, false);with idvictim-task-42. - As a second, unrelated caller with no auth context, read it back:
store.get("victim-task-42").
The second caller receives the first caller’s task in full, with no authorization check. The advisory records the observed result as:
unauthenticated get(victim-task-42) returned task owned by nobody-checked: victim-task-42 / ctx=victim-ctx
This was verified on main (commit 72d220c, JDK 21) and reproduces unchanged on 1.2.0.Final.
Detection and Mitigation
Detection
- Dependency inventory. Search the Maven dependency tree for
org.a2aproject.sdk:a2a-java-sdk-server-commonand compare the resolved version against the fixed release,1.3.0.Final. Anything below that version falls inside the OSV affected range. - Wiring review. The advisory names the exact patterns that bypass authorization: use of the default no-arg
InMemoryTaskStore, manual construction viaDefaultRequestHandler.builder().build(), and non-CDI integration such as Spring. Check whether aTaskAuthorizationProvideris configured at all, and whether requests actually route throughAuthorizationRequestHandlerDecorator. - Behavioural test in an authorized environment. The advisory’s PoC pattern — one caller saves a task, a second unrelated caller with no auth context reads it by id — can be reproduced in a test environment to confirm whether your wiring reaches the authorization check.
Mitigation
- Upgrade. The OSV range marks versions before
1.3.0.Finalas affected. The fix is associated with thev1.3.0.Finalrelease tag, pull request #1095, and commitefb4e985e99390c4fc1f78c0a187a4254c0a2553. - Interim workaround (per the advisory). Until a fixed release is deployed, configure a
TaskAuthorizationProviderand ensure requests are routed through the authorization decorator (CDI wiring), rather than relying on the default no-arg store or a manually built handler. Keep the advisory’s nuance in mind: the store’sgetpath performs no check regardless of provider, so decorator routing is not optional. - Direction of the fix (per the advisory’s remediation). Fail closed by default — deny task reads when no authorization provider is configured, rather than treating a missing provider as allow-all — and apply the authorization check in the store’s
getpath, not only inlistand the CDI decorator. The advisory further suggests that if the permissive default is retained for single-user or testing scenarios, a prominent startup warning should fire when the server comes up with no authorization provider, so it cannot be shipped by accident.
Bug Bounty Angle
For bug bounty hunters, this CVE is a case study in SDK-level defaults becoming application-level findings. The root cause lives in a library, but it manifests in every deployment that ships the default wiring — and the advisory argues that shipping it unintentionally is easy precisely because the unsafe posture is the default.
- What to look for. Targets running agent services built on the A2A Java SDK. The core question is whether task reads cross caller boundaries: obtain or observe a task id belonging to one account or session, then request that same task from an unrelated session with no authorization context. If the full task — status, context id, message history, artifacts — comes back, you are looking at the CWE-862 pattern this advisory describes.
- Why unauthenticated access may be in play. The advisory states that in the default/reference deployment the transport endpoints are served without authentication enforced, which is why the CVSS vector carries
PR:N. Depending on the target’s own authentication layer, the cross-caller read may not require any account at all. - Where to report. The upstream fix already exists — pull request #1095, commit
efb4e985e99390c4fc1f78c0a187a4254c0a2553, shipped in1.3.0.Final. For a specific deployment, the finding is that the operator shipped the default wiring on a vulnerable version. Check the program’s scope before testing: many bounty programs exclude flaws in third-party libraries unless deployment-specific impact is demonstrated. - Framing the report. Anchor it to the advisory — GHSA-qw47-mcm5-934w, affected versions before
1.3.0.Final— and identify the wiring path the target uses: default store, manual handler construction, or non-CDI integration. A report demonstrating a cross-caller read on a vulnerable version with default wiring is difficult to dispute.
Standard discipline applies: test only systems you are permitted to test, and stay within the scope and rules of the program you are working with.
Frequently Asked Questions
What is CVE-2026-111764?
A high-severity missing-authorization flaw (CWE-862) in the A2A Java SDK’s server-common package. With default wiring, task reads are not authorized, so any caller can retrieve another caller’s task — status, context, message history, and artifacts — by supplying its id. CVSS 7.5, High.
Which versions are affected?
org.a2aproject.sdk:a2a-java-sdk-server-common versions before 1.3.0.Final: the advisory lists <= 1.2.0.Final plus the 1.2.1.Final-SNAPSHOT on main prior to the fix, and the OSV range covers everything introduced from version 0 up to the fix.
Can an unauthenticated attacker exploit it?
In the default/reference deployment the advisory states transport endpoints are served without authentication enforced, and the CVSS vector uses PR:N. In that configuration, the cross-caller task read is reachable by an unauthenticated caller.
How do I fix or work around it?
Upgrade to 1.3.0.Final. As an interim workaround, configure a TaskAuthorizationProvider and route requests through the CDI authorization decorator instead of relying on the default no-arg store or a manually built handler.
References
- GitHub advisory GHSA-qw47-mcm5-934w (a2aproject/a2a-java)
- NVD entry for CVE-2026-111764
- Fix pull request #1095 (a2aproject/a2a-java)
- Fix commit efb4e985e99390c4fc1f78c0a187a4254c0a2553
- Release v1.3.0.Final
- GitHub global advisory entry for GHSA-qw47-mcm5-934w
CWE mappings: CWE-862 (Missing Authorization) and CWE-1188 (Insecure Default Initialization). Discoverer credits are not disclosed in the available sources; the CVE record is assigned by GitHub_M.
Leave a Reply