Evidence standard: four records, one verified GitSpawn RCE
The four published records concern the same project, but the public evidence does not establish one universal exploit chain. CVE-2026-71963 has the strongest record: a CNA description, an upstream pull request, a merged patch and regression tests for the automatic Git call sites. The authorization bypass, SSRF and denial-of-service records identify additional application boundaries. Composition depends on deployed versions, exposed interfaces, network placement, session design and runtime identity.
Keep four evidence layers separate: model output, application proposal, policy admission and observed effect. A transcript proves what the model returned. A policy event proves allow or deny. A child-process or target-side event is needed to prove command execution, network access or modification.
The four CVEs and the boundary each one crosses
| CVE | Published behavior | Affected record | Score | Limit |
|---|---|---|---|---|
| CVE-2026-71963 CWE-78 | Repository-local Git configuration can trigger command execution during automatic workspace inspection. | 0.18.2–0.21.0; fixed in commit f6234d0. | 8.8 v3.1 8.6 v4.0 | Establishes the RCE mechanism, not compromise of every deployment. |
| CVE-2026-85105 CWE-639 / CWE-285 | A controlled session_id reaches _sess_nowait and bypasses authorization. | 0.18.0 is explicitly listed. | 7.3 v3.1 6.9 v4.0 | No complete affected range or fix is published in the CNA record. |
| CVE-2026-85106 CWE-918 | fetchLinkTitle performs a server-side request to a controlled URL. | 0.18.0 is explicitly listed. | 6.3 v3.1 5.3 v4.0 | The v3.1 vector requires low privileges; internal impact depends on egress and returned data. |
| CVE-2026-84287 CWE-404 | The session chat API can be driven into denial of service. | 0.18.0 is explicitly listed. | 4.3 v3.1 5.3 v4.0 | The public record does not identify the exact vulnerable function. |
Investigation rule: record installed build, interface exposure and acting identity before assigning combined-chain impact. CVE adjacency creates a hypothesis; correlated effects prove a path.
GitSpawn anatomy: when inspection becomes execution
Hermes gathered coding context by running the system Git binary in the selected session directory. The upstream patch says workspace snapshots, project-tree discovery, diff context, goal fingerprints and worktree setup could run before a prompt, visible tool approval or trust gate. Git configuration can select executable behavior. The official Git documentation defines core.fsmonitor as a hook pathname when its value is not Boolean.
.git metadata.The delivery condition matters. The upstream fix notes that ordinary git clone does not transfer another repository's local .git/config. Directory archives, synchronized folders and removable-media workspaces can retain it. The fix therefore hardens every automatic Git path, rather than relying on users to recognize one malicious key.
The patched design supplies a controlled noninteractive Git environment that neutralizes repository-selected fsmonitor, hooks, pager, editor and credential helpers while ignoring global and system configuration. Diff-rendering calls also receive --no-ext-diff and --no-textconv; attacker-named diff drivers cannot be exhaustively disabled by guessing configuration keys.
textdef inspect_workspace(repo):
env = inert_git_configuration()
args = harden_diff_arguments(["status", "--porcelain"])
return run(["git", *args], cwd=repo, env=env,
stdin=DEVNULL, timeout=bounded_seconds)
# Required property: automatic inspection cannot select
# repository-defined executables or credential helpers.
Containerization reduces impact only when the agent lacks host credential mounts, broad workspaces, runtime sockets and unrestricted egress. The decisive question is which identity and resources the Git child process actually receives.
Session authorization, URL fetch and availability
Session objects need subject and tenant authorization
CVE-2026-85105 maps to CWE-639 and CWE-285. A controlled session identifier reaches the session lookup path. The server should authenticate the caller, load the requested session, compare its owner and tenant, then authorize the requested read, update, delete or delegation function. Possession of an identifier does not confer authority.
SSRF is destination authorization
CVE-2026-85106 maps to CWE-918. A link-title feature fetches a caller-selected URL. Exposure depends on parsing, DNS results, redirects, scheme restrictions, egress policy and response handling. Validate every resolved destination after redirects, block prohibited loopback, link-local and private ranges, limit response size and isolate the fetcher from privileged internal services.
Availability claims require observed resource effects
CVE-2026-84287 identifies the session chat interface but does not disclose the exact failing function. Avoid inventing a root cause. In an authorized environment, measure requester identity, endpoint, concurrency, resource use, health failures and recovery. Apply request-size limits, per-identity concurrency budgets, timeouts and workload isolation according to the observed bottleneck.
Interactive mindmap: inputs, authority and evidence
Expand each branch to follow its trust boundary and the evidence required to confirm it. The map keeps the records separate so reviewers can see where a proposed composition still lacks proof.
Repository metadata
Copied .git metadata → automatic Git probe → repository-selected executable behavior → user-process authority. Confirm with repository provenance, version, process ancestry and patch state.
Session object
Request → authenticated subject → session lookup → tenant/owner/function decision. Confirm with request, subject, object owner, policy outcome and returned object.
URL fetch
Controlled URL → parser → DNS/redirect resolution → egress decision → destination. Confirm every resolved address, network decision, requester and response handling.
Chat availability
Request stream → session handler → bounded resources → health and recovery. Confirm the resource and service effect without guessing the undisclosed implementation defect.
A defensible combined path names every required edge: entry point, accepted input, authorization result, invoked component, executing identity and target-side effect. If session access does not reach repository selection, or the fetcher cannot reach sensitive destinations, that proposed edge remains unproven.
Detection and forensic triage
| Signal | Source | Supports | Does not prove |
|---|---|---|---|
| Unexpected child below Git | Endpoint process telemetry | Inspection started another executable. | Which configuration key selected it. |
| Executable Git keys | Quarantined repository metadata | A relevant precondition exists. | That execution occurred. |
| Subject differs from session owner | API and policy events | Possible ownership failure. | Impact without returned or changed data. |
| Fetcher reaches restricted ranges | DNS, proxy and firewall | SSRF attempt or policy failure. | Data disclosure unless the response path is observed. |
| Worker exhaustion | Gateway and runtime metrics | Availability effect and recovery time. | The undisclosed defect's root cause. |
bashset -euo pipefail
events_file="${1:?usage: review-events.sh EVENTS.jsonl}"
jq -c '
select(
(.process.parent == "git" and .process.image != "git") or
(.policy.decision == "deny" and .effect.observed == true) or
(.network.destination_class | IN("loopback","link-local","private"))
)
| {time, request_id, run_id, subject, tenant,
process, policy, network, effect}
' "$events_file"
This example expects normalized defensive events. Adapt its fields to your telemetry. Preserve request, run and process identifiers while excluding raw API keys, authorization headers and unrestricted prompt content.
Remediation checklist
0 controls verified
If a potentially affected runtime held provider, source-control, registry or cloud credentials, rotate them according to observed exposure and incident policy. A vulnerable version establishes urgency; it does not by itself prove credential theft.
Verification runbook and primary sources
Run ancestry checks against a trusted Hermes source checkout, outside any untrusted workspace. The CVE record identifies a fixing commit but does not name a fixed release. Confirm that the deployed build contains the commit or obtain a vendor release statement before declaring remediation.
bashset -euo pipefail
agent_source="${1:?usage: verify-hermes.sh TRUSTED_HERMES_SOURCE}"
fixed_commit="f6234d00c5d59450adea1d7edd30ad3859375c79"
current_commit="$(git -C "$agent_source" rev-parse HEAD)"
printf 'Hermes source commit: %s\n' "$current_commit"
if git -C "$agent_source" merge-base --is-ancestor "$fixed_commit" HEAD; then
printf 'GitSpawn fix commit is present.\n'
else
printf 'GitSpawn fix commit was not found.\n' >&2
exit 1
fi
- CVE-2026-71963 official record
- Upstream fix analysis and regression evidence
- Upstream fix commit f6234d0
- CVE-2026-85105 official record
- CVE-2026-85106 official record
- CVE-2026-84287 official record
- Git core.fsmonitor documentation
- OWASP SSRF prevention guidance
Model output is not system action. Here, the strongest action boundary sits below the model: automatic context gathering invokes a trusted system tool whose local configuration can select executable behavior. Secure agent deployments constrain the application, subprocess, identity and network boundaries even when the model never requests a tool.
