Repository navigation
fix: close the credential leaks two security reviews found - #93
Merged
Merged
Conversation
Independent reviews by Codex and Claude Fable, then three adversarial passes over the fixes, found ways a credential reached somewhere it should not: - --exec passed $GITHUB_APP_PRIVATE_KEY to the command, and the clone default to git. Both now get an environment without it or any exported token, matched case-insensitively on Windows. - A --key that is neither PEM nor a file, such as a base64 CI secret, was repeated in full in the error. A value longer than a path no longer is. - GH_HOST dropped the API's port, so gh sent the token to 443. Ports are kept, a host with one is never rewritten, and IPv6 keeps its brackets. A clone's http(s) origin must name the API's port too, 443 included, since git push hands the token to it. - An exported GH_HOST naming another instance made gh send the token there. token --exec now exits 2 before minting; the JWT is left alone, since only the caller knows its App's instance. - A SIGINT sent to githubauth alone left the command running. On Linux and macOS it is passed on unless the command is in the terminal's foreground job, which got the Ctrl-C itself. - Successful responses are read up to 16 MiB, and every workflow action is pinned to a commit, since the release job holds the publishing PAT. Docs say to pass the PEM through the environment or stdin, not argv, and that revoking a token does not clear a source's cache.
jferrl
force-pushed
the
fix/security-review
branch
from
October 31, 2026 09:48
6b9d37e to
2212e46
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #93 +/- ##
==========================================
- Coverage 97.93% 97.68% -0.25%
==========================================
Files 8 9 +1
Lines 871 908 +37
==========================================
+ Hits 853 887 +34
- Misses 18 21 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent full-repository security reviews, Codex (
gpt-6.1-sol, reasoningultra) and Claude Fable, found ten issues, none overlapping beyond two. The serious one:githubauth token --execpassed the App's private key, which mints tokens for every installation, to the command it runs. This PR fixes all ten. Three further adversarial Codex passes over the fixes found thirteen more gaps in them, also fixed. Stacked on #92, whose clone default two of the fixes touch.What this does
--execcommand, andgitfor the clone default, saw$GITHUB_APP_PRIVATE_KEY--keywas echoed in full in the error, into logs and agent transcripts--enterprise-url https://ghe:8443setGH_HOST=ghe, soghsent the token to 443GH_HOST=ghe:8443GH_HOSTfor another instance madeghsend the token theretoken --execexits 2 before mintinggit pushwould hand the token to that portkill -INTon githubauth left the command running with the tokenChanges
childEnviron()drops the key and exported tokens for every process githubauth starts.ghHostkeeps any port except https's 443, never rewrites a host with one, and keeps IPv6 brackets.originRepocompares an http(s) origin's host and port, an ssh origin's host only.checkGHHostrefuses a mismatchedGH_HOSTfortoken --exec. The JWT is not checked: it is signed locally.uses:is pinned to a SHA with its version.Rationale
The
GH_HOSTmismatch exits rather than warns, since a warning would still send the token. A--base-urlproxy in front of github.com, for which v1.11.0 suggested exportingGH_HOST, sets it inside the command instead:--exec -- env GH_HOST=github.com gh …. That is under Changed in the CHANGELOG.The ports and foreground rules each fail closed: an unusual setup gets exit 2 or a
ghconnection error, never a token on another port.Migration Notes
None beyond the
GH_HOSTchange above. Every new test fails with its fix undone. Verified against a real App: from an https clone ofgopherguru/test, the child got a token scoped to it and noGITHUB_APP_PRIVATE_KEY. Foreground detection was checked under a real pseudo-terminal and in a session without one.Known and left: on macOS, Go documents a narrow window in which a signal can reach a reused PID after the child exits, inherited from the runtime and already true of SIGTERM.
🤖 Generated with Claude Code