Skip to content

fix: scrub checkout credential includes - #3

Merged
kostua16 merged 4 commits into
mainfrom
codex/harden-checkout-v6-auth-cleanup
Jun 28, 2026
Merged

fix: scrub checkout credential includes#3
kostua16 merged 4 commits into
mainfrom
codex/harden-checkout-v6-auth-cleanup

Conversation

@kostua16

Copy link
Copy Markdown
Owner

fix: scrub checkout credential includes

Root cause:

  • actions/checkout v6 can persist GitHub auth through local includeIf.gitdir entries that load RUNNER_TEMP git-credentials-.config files, so clearing direct local http..extraheader keys is not enough.
  • Reused self-hosted runner workspaces can also retain embedded credentials in remote.origin.url.

Changes:

  • Remove only checkout-style local includeIf.gitdir path values pointing at runner temp git-credentials-*.config files.
  • Preserve unrelated includeIf entries and non-matching temp paths.
  • Sanitize configured-host remote.origin.url values with embedded userinfo without writing tokenized URLs.
  • Add source-based tests for direct extraheader cleanup, includeIf preservation/removal, remote URL cleanup/preservation, and redacted debug output.
  • Document the new behavior.

Validation:

  • npm run typecheck
  • npm test
  • npm run build
  • git diff --check

Impact:

  • Keeps auth cleanup local to the worktree; global and system Git config are not mutated.
  • Build time impact is minimal; tests add small temporary Git repository scenarios.

Comment thread src/main.ts Outdated
function isPathUnder(parent: string, child: string) {
const normalizedParent = normalizePathForComparison(tryRealpath(parent));
const normalizedChild = normalizePathForComparison(tryRealpath(child));
const relative = normalizedChild.slice(normalizedParent.length);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: isPathUnder never confirms that normalizedChild actually starts with normalizedParent.

relative = normalizedChild.slice(normalizedParent.length) is only meaningful when the child is a prefix-extension of the parent. Without checking normalizedChild.startsWith(normalizedParent) first, a child that does not share the parent prefix can still produce a relative substring that starts with / or \, causing a false-positive match. For example isPathUnder("/a/b", "/x/y/z") returns true (relative becomes "/z"). In practice this means an includeIf value not under RUNNER_TEMP could be classified as under it and get scrubbed, removing a legitimate user include. Verify the prefix (with a separator boundary) before computing the relative slice.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread src/main.ts Outdated
if (parsed.hostname.toLowerCase() !== serverUrl.hostname.toLowerCase()) {
return undefined;
}
if (parsed.port !== serverUrl.port) return undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: An explicit default port on the configured host lets embedded credentials survive the scrub.

parsed.port !== serverUrl.port is a strict string compare with no default-port normalization. A remote.origin.url such as https://x-access-token:token@github.com:443/owner/repo.git for serverUrl = https://github.com gives parsed.port = "443" vs serverUrl.port = "", so cleanConfiguredHostRemoteUrl returns undefined and the embedded token is left in place. Treat https/443 and http/80 as equivalent to an empty port (or compare via new URL default-port resolution) before deciding to scrub.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The two previously-reported issues (isPathUnder prefix omission and strict port compare in cleanConfiguredHostRemoteUrl) are verified fixed in the current code. The incremental change since the last review only bumps vite (^4.5.0 → ^6.4.3) and regenerates the lockfile; no new issues found.

Files Reviewed (2 files)
  • package.json
  • package-lock.json (generated, skipped for findings)
Previous Review Summaries (2 snapshots, latest commit 6f89ae0)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 6f89ae0)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • src/main.ts
  • test/main.test.mjs

Previous review (commit 17125c8)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/main.ts 195 isPathUnder does not verify normalizedChild starts with normalizedParent, causing false-positive parent/child matches and possible removal of legitimate includeIf entries.
src/main.ts 259 cleanConfiguredHostRemoteUrl uses a strict port compare; a configured-host remote.origin.url with an explicit default port (e.g. :443) escapes credential scrubbing.
Files Reviewed (6 files)
  • src/main.ts - 2 issues
  • test/main.test.mjs
  • README.md
  • package.json
  • vite.config.ts
  • package-lock.json (generated, skipped for findings)

Fix these issues in Kilo Cloud


Reviewed by glm-5.2-short · Input: 31K · Output: 2.5K · Cached: 278.2K

@kostua16
kostua16 merged commit c632003 into main Jun 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant