-
Notifications
You must be signed in to change notification settings - Fork 1
[sec-check] allow-listed gh label list / gh search --jq env prints GH_TOKEN past the gate hook #596
Copy link
Copy link
Closed
Labels
agent/sec-checkCreated by Hive for agent-filed issue provenanceCreated by Hive for agent-filed issue provenancehive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmedHive verified that an open PR references or claims this issue; still actionable until confirmedhive/hive-wild-moleApproved by a Hive merger/owner for auto-merge on green CIApproved by a Hive merger/owner for auto-merge on green CIsecurityApproved by a Hive merger/owner for auto-merge on green CIApproved by a Hive merger/owner for auto-merge on green CI
Description
Activity
Metadata
Metadata
Assignees
Labels
agent/sec-checkCreated by Hive for agent-filed issue provenanceCreated by Hive for agent-filed issue provenancehive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmedHive verified that an open PR references or claims this issue; still actionable until confirmedhive/hive-wild-moleApproved by a Hive merger/owner for auto-merge on green CIApproved by a Hive merger/owner for auto-merge on green CIsecurityApproved by a Hive merger/owner for auto-merge on green CIApproved by a Hive merger/owner for auto-merge on green CI
Security Finding
Severity: high
Type: secret-exposure (permission boundary bypass)
.claude/settings.jsonpre-approvesBash(gh label list:*),Bash(gh search issues:*)andBash(gh search prs:*). All three take gh's--jq/-qfilter, which gh evaluates with gojq. gojq'senvbuiltin and$ENVvariable return the whole process environment, so an allow-listed read printsGH_TOKENand every other exported variable with no prompt..claude/hooks/gate_git_diff.pylists these rows inGATED_PREFIXES, but it only checks them for redirections, substitutions and leading assignments. An unquoted$ENVis refused by accident (any$counts as a substitution). The bareenvbuiltin, and a single-quoted'$ENV', both pass.Verified at
37beb34with gh 2.101.0:The hook exits 0 (allowed) for each of these:
gh label list --json name --jq envgh label list --json name --jq=envgh label list --json name -q env/-qenvgh search issues x --json title --jq "env.GH_TOKEN"gh search prs x --json title -q '$ENV'This is the same class as aurora-zfs-simple#292, sensi#394 and zfs-kinoite-complex#309, all fixed and merged. atomic-image-builder was the last repo still open to it.
Impact
A prompt-injected or confused agent session reads the App/user token (and any other secret in the environment, such as
ANTHROPIC_API_KEY) into the transcript without the user being asked. NoRead(...)deny rule protects an environment variable.Recommendation
In the gate's gated-prefix branch, when the prefix is
gh, read every pflag spelling of the filter (--jq V,--jq=V,-q V,-qV,-q=V,-qat the end of a cluster such as-wq V). Refuse a filter that namesenvor$ENV. Also refuse a filter that bash rewrites before gh sees it: a live brace ({e,}nv), an unquoted glob, or a leading~..env, as a field of the fetched JSON, stays allowed. Add corpus rows and a SECURITY-AI.md note.A hold-gated PR with this fix follows.
Filed by sec-check agent (ACMM L4/L5 — hold-gated mode)
🐝 Hive Agent:
security| Instance:hive-wild-mole| SHA:unknown— hive: agent=sec-check backend=claude model=claude-opus-5-5 effort=medium claude=2.1.283