Commit Graph

4 Commits

Author SHA1 Message Date
Carlos Florêncio 1f905be98f fix: support long Git worktree paths on Windows (#1878) 2026-07-23 20:21:23 +01:00
João Salavisa ac8401b709 fix: harden submodule init against malicious .gitmodules (#1802)
* fix: harden submodule init against malicious .gitmodules

initSubmodules ran a bare `git submodule update --init --recursive` in a
worktree whose HEAD is attacker-controlled during a fork-PR review task,
with no protocol restriction, no hooks disable, and no cmd.Env. Attacker
`.gitmodules` could pick a command-executing transport (`ext::sh -c`,
CVE-2018-17456), a local `file://` path, or a plain-http URL (cloud
metadata SSRF).

Harden the single sink so all call sites benefit:
- protocol.allow=never default-denies every transport; only https/ssh are
  re-enabled (blocks file://, git://, plain http:// SSRF).
- protocol.ext.allow=never hard-pins the RCE transport off; on the command
  line it outranks any ambient protocol.ext.allow=always.
- core.hooksPath=/dev/null neutralizes attacker-planted hooks.
- GIT_TERMINAL_PROMPT=0 stops attacker URLs from hanging on a prompt.

Residual: attacker-chosen https/ssh URLs are still fetched (transports real
submodules require); fully closing that needs gating submodule init off for
untrusted worktrees, tracked separately.

* fix: address submodule hardening review feedback

- Reuse newNonInteractiveGitCmd so submodule init inherits the full
  non-interactive env set (GIT_SSH_COMMAND=ssh -oBatchMode=yes, SSH/GCM
  askpass suppression, WaitDelay). Prevents an attacker ssh:// submodule
  URL from hanging the review runner on host-key/passphrase prompts until
  the context deadline (GIT_TERMINAL_PROMPT=0 alone only covers git's HTTP
  prompt, not SSH).
- Correct the file:// comment: command-line -c outranks repo/global git
  config, so ambient protocol.file.allow=always does NOT re-enable file
  submodules here. This is intentional for untrusted trees; a trusted
  opt-in must be an explicit per-repo -c, not implicit host config.
- Add a file:// URL variant to the transport-block test alongside the
  bare-path form (CVE-2022-39253 classification differs by git version).

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-07-19 16:12:56 +01:00
Carlos Florêncio a8db7478ac fix(backend): cap gh/git fork concurrency via shared subproc throttles (#1216) 2026-06-01 20:35:43 +01:00
José Almeida e86b6655a3 fix(worktree): handle submodules in worktree creation (#579)
* fix(worktree): handle submodules in worktree creation

Repos with git submodules failed during worktree creation when git-crypt
was also present. The `git checkout HEAD -- .` command in
unlockGitCryptAndCheckout() tried to process submodule gitlink entries,
but git resolved their git dirs relative to the worktree-specific git
dir instead of the common dir, causing "not a git repository" errors.

- Detect submodule paths via `git ls-tree -r HEAD` (mode 160000)
- Exclude submodule paths from git-crypt checkout using :(exclude) pathspecs
- Initialize submodules after worktree creation via `git submodule update --init`
  (non-fatal — unreachable URLs are logged as warnings)
- Add submodule init to all worktree creation paths (git-crypt and non-git-crypt)

* fix(worktree): address review — recursive submodule init, consistent call sites

- Add --recursive to git submodule update --init for nested submodules
- Call initSubmodules unconditionally in git-crypt path (matching manager.go)

* fix(worktree): restore submodule index entries after git-crypt checkout

The :(exclude) pathspec used to skip submodules during git checkout also
prevents their gitlink entries from being written to the index. This
leaves git status showing them as staged deletions.

After checkout, run git reset HEAD for each excluded submodule path to
copy the gitlink entry from HEAD back into the index.

* test(worktree): add git status assertion to submodule unlock test

Validate that the index reset after :(exclude) checkout leaves no
staged deletions for submodule paths.

* fix(worktree): use literal pathspec for submodule exclusion

Use :(literal,exclude) instead of :(exclude) to prevent glob
metacharacters in submodule paths from being interpreted as patterns.

* fix(worktree): fix initSubmodules docstring to match --recursive flag
2026-04-14 15:59:25 +01:00