Summary
Hector documents an app JWT model. On the A2A path, tasks are stored by app plus task id, while message.metadata.user_id can override the authenticated subject before session selection. In the replay, Bob holds the same app JWT as Alice, reads Alice's task by taskId, and then sends metadata.user_id=alice with Alice's contextId to enter Alice's downstream session.
Affected Target Verified
- Repository:
https://github.com/verikod/hector
- Component: A2A JSON-RPC handler under
/agents/{agent}
- Affected commit verified:
abe472b6deb12b3dbba290dbec44cd3be27e163d
- Vulnerability type: Authorization bypass within a shared app-token boundary
Preconditions
- One app JWT is shared by multiple end users or local callers.
- The app expects
metadata.user_id to represent end-user identity.
- A task id or context id leaks through normal application flow or logs.
Steps To Reproduce
From the attachment directory:
The script clones the target repository, checks out the verified commit, prepares a local test environment, and runs the bundled PoC. It does not contact attacker-controlled services; the setup only downloads the public repository and normal build dependencies.
To run against an existing checkout:
HECTOR_TARGET_DIR=/path/to/checkout bash reproduce.sh
The wrapper accepts HECTOR_TARGET_DIR for an existing checkout. It also accepts the target commit override documented in attachments/reproduce.sh.
Technical Details
The JWT subject identifies the app. The A2A event path derives userID from claims, then lets caller-controlled message.metadata.user_id override it. Sessions are keyed as appName:userID:sessionID; tasks are persisted as (app_name, id) without a user dimension.
Expected Behavior
End-user identity inside an authenticated app should come from a trusted claim
or app-verified mapping, not from caller-controlled A2A message metadata. Task
reads and session lookup should include that trusted user dimension when an app
token is shared by multiple users.
Actual Behavior
- Bob can
tasks/get Alice's task and receive Alice's secret-bearing artifact/history.
- Bob using
metadata.user_id=bob on Alice context does not see Alice memory.
- Bob using
metadata.user_id=alice on the same context receives Alice memory.
Impact
Any holder of the shared app token can select another end-user namespace by
supplying message.metadata.user_id. In the reproduced flow, Bob's own
metadata.user_id=bob request does not see Alice's memory, but
metadata.user_id=alice with Alice's context enters Alice's downstream
session.
For deployments where one app token represents an application and multiple end
users are distinguished inside that app, this lets one local caller or peer
read another user's task artifacts/history by task id and then join that user's
session context. The exposed data can include prompts, agent responses,
workflow artifacts, and user-specific memory stored under the app/user/session
tuple.
The issue also weakens audit and attribution. The authenticated token still
identifies the app, but the end-user authority used for session selection comes
from caller-controlled A2A metadata, so later actions may be recorded or
processed under the wrong end-user namespace.
Suggested Fix
Do not trust A2A message metadata for user authority. Derive end-user identity from a trusted authenticated claim or an app-verified mapping, and include that identity in task reads and session lookup.
Attachments
attachments.zip
Summary
Hector documents an app JWT model. On the A2A path, tasks are stored by app plus task id, while
message.metadata.user_idcan override the authenticated subject before session selection. In the replay, Bob holds the same app JWT as Alice, reads Alice's task bytaskId, and then sendsmetadata.user_id=alicewith Alice'scontextIdto enter Alice's downstream session.Affected Target Verified
https://github.com/verikod/hector/agents/{agent}abe472b6deb12b3dbba290dbec44cd3be27e163dPreconditions
metadata.user_idto represent end-user identity.Steps To Reproduce
From the attachment directory:
The script clones the target repository, checks out the verified commit, prepares a local test environment, and runs the bundled PoC. It does not contact attacker-controlled services; the setup only downloads the public repository and normal build dependencies.
To run against an existing checkout:
The wrapper accepts
HECTOR_TARGET_DIRfor an existing checkout. It also accepts the target commit override documented inattachments/reproduce.sh.Technical Details
The JWT subject identifies the app. The A2A event path derives
userIDfrom claims, then lets caller-controlledmessage.metadata.user_idoverride it. Sessions are keyed asappName:userID:sessionID; tasks are persisted as(app_name, id)without a user dimension.Expected Behavior
End-user identity inside an authenticated app should come from a trusted claim
or app-verified mapping, not from caller-controlled A2A message metadata. Task
reads and session lookup should include that trusted user dimension when an app
token is shared by multiple users.
Actual Behavior
tasks/getAlice's task and receive Alice's secret-bearing artifact/history.metadata.user_id=bobon Alice context does not see Alice memory.metadata.user_id=aliceon the same context receives Alice memory.Impact
Any holder of the shared app token can select another end-user namespace by
supplying
message.metadata.user_id. In the reproduced flow, Bob's ownmetadata.user_id=bobrequest does not see Alice's memory, butmetadata.user_id=alicewith Alice's context enters Alice's downstreamsession.
For deployments where one app token represents an application and multiple end
users are distinguished inside that app, this lets one local caller or peer
read another user's task artifacts/history by task id and then join that user's
session context. The exposed data can include prompts, agent responses,
workflow artifacts, and user-specific memory stored under the app/user/session
tuple.
The issue also weakens audit and attribution. The authenticated token still
identifies the app, but the end-user authority used for session selection comes
from caller-controlled A2A metadata, so later actions may be recorded or
processed under the wrong end-user namespace.
Suggested Fix
Do not trust A2A message metadata for user authority. Derive end-user identity from a trusted authenticated claim or an app-verified mapping, and include that identity in task reads and session lookup.
Attachments
attachments.zip