Repository navigation
fix(git): redact URL credentials in GitError message, argv, and stderr - #562
Merged
Merged
Conversation
Contributor
|
Standing release PR: #555 · v0.40.1 queued (4 packages) · open 1h 21m · ✅ ready to merge Release Preview — v0.40.0 → v0.40.1
These changes will be added to the release PR (#555) when merged: Changelogmonorepo 0.40.0 → 0.40.1
After merge — predicted release
Updated automatically by ReleaseKit |
An authenticated push/fetch remote (https://x-access-token:<token>@github.com/…) rode the failed argv — and git's own stderr — into GitError, which surfaces in CI logs and the failure-report PR comment on any push failure. Mask the user:password userinfo at the GitError construction choke point so every construction site is covered; the array handed to the runner is untouched, so the real push still uses the real URL. Refs #557 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011i1KvoyxATU3bz5V5Sf1Xu
goosewobbler
force-pushed
the
fix/git-error-token-redaction
branch
from
July 19, 2026 15:26
78fa7bf to
95ba88f
Compare
This was referenced Jul 19, 2026
Merged
Closed
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.
What
Mask
user:password@userinfo in any URL embedded in aGitError'smessage,args, andstderr, at the constructor choke point in@releasekit/git.Why
When
git.httpsTokenEnvis configured, the push remote is an authenticated URL (https://x-access-token:<token>@github.com/…). On any push failure (e.g. a branch-protection ruleset rejection), that URL rode the failed argv — and git's own stderr — intoGitError.message, which propagates intoPipelineError→ the failure-report PR comment (world-readable on public repos) and CI logs. GitHub's log masking doesn't apply to comment bodies, so the token was disclosed.How
redactUrlCredentials()does a linear (no-backtracking) scan overscheme://userinfo@spans and replaces the userinfo with***.GitErrorconstructor so every construction site is covered without each caller remembering. The array handed to the runner is untouched (a redacted copy is stored), so the real push still uses the real URL.Tests
GitErrorwhosemessage/args/stderrcontain no token and showhttps://***@github.com/o/r.git.redactUrlCredentialsmasksuser:pass@spans and leaves credential-free / scp-style remotes intact.Closes #557
Greptile Summary
This PR fixes a credential-disclosure vulnerability where authenticated HTTPS remote URLs were leaking into
GitError.message,.args, and.stderr, which propagate to the failure-report PR comment and CI logs.redactUrlCredentials(text)using a linear regex anchored on the literal://that replaces the userinfo segment with***, avoiding ReDoS via a negated character class instead of a quantified scheme prefix.GitErrorconstructor so all construction sites are covered without per-caller changes; the real args array passed to the runner is left untouched so the live push still uses the real URL.Confidence Score: 5/5
Safe to merge — the change is a well-scoped security fix applied at a single constructor choke point with no changes to the live call path.
The regex is intentionally linear (negated character class anchored on
://, no alternation or nested quantifiers), is applied in theGitErrorconstructor so every call site is covered automatically, and the real args array handed to the runner is untouched. Tests cover end-to-end push failure redaction, multi-URL strings, credential-free URLs, scp-style remotes, and the adversarial-length input. No defects found.No files require special attention.
Important Files Changed
redactUrlCredentialsand wires it into theGitErrorconstructor; regex is linear, handles all tested credential formats, and correctly excludes/to respect the authority boundary.Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Runner as GitRunner participant GitCli as GitCli.push() participant GitError as GitError constructor participant Caller as Caller / PipelineError GitCli->>Runner: run(['push','--', authenticatedRemoteUrl, ...]) Runner-->>GitCli: throws exec error (exit 128, stderr with URL) GitCli->>GitError: new GitError(message, args, exitCode, stderr) Note over GitError: redactUrlCredentials applied to message, each arg, and stderr GitError-->>Caller: "GitError with credentials replaced by ***" Note over Caller: Token never reaches PR comment or CI logs%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant Runner as GitRunner participant GitCli as GitCli.push() participant GitError as GitError constructor participant Caller as Caller / PipelineError GitCli->>Runner: run(['push','--', authenticatedRemoteUrl, ...]) Runner-->>GitCli: throws exec error (exit 128, stderr with URL) GitCli->>GitError: new GitError(message, args, exitCode, stderr) Note over GitError: redactUrlCredentials applied to message, each arg, and stderr GitError-->>Caller: "GitError with credentials replaced by ***" Note over Caller: Token never reaches PR comment or CI logsReviews (2): Last reviewed commit: "fix(git): redact URL credentials in GitE..." | Re-trigger Greptile