Skip to content

fix(run): refuse symlinked .git / .git/config for the config overlay - #111

Merged
sbp-bvanb merged 2 commits into
schubergphilis:mainfrom
Joeri-Abbo:fix/refuse-symlinked-git-config
Sep 29, 2026
Merged

sbp-bvanb merged 2 commits into
schubergphilis:mainfrom
Joeri-Abbo:fix/refuse-symlinked-git-config

Conversation

@Joeri-Abbo

Copy link
Copy Markdown
Member

What

The container-only .git/config overlay in run.sh is now built only when .git is a real directory and .git/config a regular file — neither may be a symlink.

run.sh runs host-side, and [ -f ] / cp follow symlinks. The workspace is writable from the container, so a .git or .git/config symlink planted during one session made the next launch copy the link's host-side target into the stage dir and mount it into the container — a read of a host file outside the passed workspaces, which the threat model lists as protected.

  • run.sh: symlink checks on both .git and .git/config.
  • tests/test_git_config_overlay.py: stdlib test that runs the real run.sh against a fake docker recording its argv; covers a real repo, a symlinked .git, and a symlinked .git/config.
  • README "Git worktrees": one sentence on symlinks being skipped.
  • OpenSpec change refuse-symlinked-git-config (archived; multi-workspace-mounts gains a scenario).

Testing

  • python3 -m unittest discover -s tests -p 'test_*.py': 117 pass. The new test fails 2 of 3 cases against main's run.sh.
  • shellcheck -S warning run.sh: clean.
  • openspec validate refuse-symlinked-git-config --strict: passes.
  • Not run: image build / smoke — host-side run.sh change only.

Touches the same loop and generated spec as the .git/hooks read-only PR; whichever lands second needs a trivial rebase (keep both spec sections).

🤖 Generated with Claude Code

The container-only .git/config overlay was built with [ -f ] and cp, which
both follow symlinks. Workspaces are writable from the container, so the
overlay step must not follow links out of the workspace. Overlay only when
.git is a real directory and .git/config a regular file, neither a symlink.

Adds tests/test_git_config_overlay.py, which runs the real run.sh against a
stub runtime, and the archived OpenSpec change with the synced
multi-workspace-mounts spec.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@stefanwb stefanwb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Joeri, this closes a real hole in something the threat model lists as protected, with a small fix. The new test runs in CI's unittest step. Approving.

@sbp-bvanb
sbp-bvanb merged commit aea1061 into schubergphilis:main Sep 29, 2026
7 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.

3 participants