Skip to content

fix(server): block additional git code-execution vectors in DockerSandboxAdapter - #916

Merged
FelixTJDietrich merged 1 commit into
mainfrom
fix/application-server-block-additional-git-vectors
Mar 25, 2026
Merged

fix(server): block additional git code-execution vectors in DockerSandboxAdapter#916
FelixTJDietrich merged 1 commit into
mainfrom
fix/application-server-block-additional-git-vectors

Conversation

@FelixTJDietrich

@FelixTJDietrich FelixTJDietrich commented Mar 24, 2026

Copy link
Copy Markdown
Collaborator

Description

Closes #904.

Found during PE audit of PR #892: DockerSandboxAdapter blocks core.hooksPath and core.fsmonitor via GIT_CONFIG_COUNT, but several additional code-execution vectors were unblocked — a malicious .git/config in a cloned repo could execute arbitrary commands when the agent runs git diff, git commit, or uses SSH/credential prompts.

This PR hardens the git security surface across three independent defense layers, and fixes a bug where git security configs were only injected when volume mounts were present (missing protection for repos cloned at runtime).

Changes

1. Extracted GIT_SECURITY_CONFIGS constant (11 git config keys)

Declarative, auditable list of git config key-value pairs injected via GIT_CONFIG_COUNT/GIT_CONFIG_KEY_*/GIT_CONFIG_VALUE_* env vars (highest precedence in git — overrides .git/config):

Config Key Safe Value Attack Vector Blocked
core.hooksPath /nonexistent Hook execution on commit/merge/checkout (existing)
core.fsmonitor false FS monitor command execution (existing)
core.sshCommand "" Arbitrary command on SSH operations
core.askPass "" Arbitrary command on credential prompts
core.editor "" Arbitrary command on git commit, git rebase -i
core.pager cat Arbitrary command on any paged output (git diff, git log)
core.gitProxy "" Shell command execution for git:// protocol
sequence.editor "" Arbitrary command on interactive rebase
credential.helper "" Arbitrary command on authentication
diff.external "" Arbitrary command on git diff
protocol.ext.allow never RCE via ext:: transport protocol (CVE-2022-25912)

2. Fixed condition gate bug (security gap)

Previously, git security configs were only injected when spec.volumeMounts() was non-empty. If the agent ran git clone at runtime (no pre-mounted repos), none of the git security configs were active. Now:

  • safe.directory entries: only when volume mounts are present (path-specific)
  • All security configs: always injected

3. Blocked git-related env vars from callers

Added to BLOCKED_ENV_VARS (exact match, case-insensitive):

  • GIT_SSH, GIT_SSH_COMMAND, GIT_ASKPASS, GIT_EDITOR, GIT_EXEC_PATH, GIT_TEMPLATE_DIR — direct command execution
  • GIT_EXTERNAL_DIFF, GIT_PROXY_COMMAND, GIT_SEQUENCE_EDITOR, GIT_PAGER — override config equivalents independently
  • GIT_TERMINAL_PROMPT, GIT_ATTR_NOSYSTEM — prevent callers from overriding hardening vars

Added GIT_CONFIG_ to BLOCKED_ENV_PREFIXES to prevent callers from injecting GIT_CONFIG_COUNT/GIT_CONFIG_KEY_*/GIT_CONFIG_VALUE_* that could override our security settings.

4. Additional hardening env vars

  • GIT_TERMINAL_PROMPT=0 — prevents git from prompting interactively (would hang the agent)
  • GIT_ATTR_NOSYSTEM=1 — prevents system-wide gitattributes from being loaded

Known Limitations (tracked follow-ups)

  • filter.*.clean/filter.*.smudge/filter.*.process — wildcard-keyed configs that cannot be enumerated or blocked via GIT_CONFIG_COUNT. A malicious repo can ship .gitattributes + .git/config with filter.evil.clean=/exploit. Requires .git/config sanitization post-clone.
  • merge.*.driver/diff.*.textconv — same wildcard limitation; lower priority since they require explicit merge/diff tool invocation.

How to Test

Unit tests (75 tests in DockerSandboxAdapterTest):

cd server/application-server && mvn test -Dsurefire.includedGroups="unit" -Dmaven.test.skip=false -DskipTests=false -Dtest="DockerSandboxAdapterTest" --batch-mode -q

Architecture tests (9 tests):

cd server/application-server && mvn test -Dsurefire.includedGroups="architecture" -Dmaven.test.skip=false -DskipTests=false -Dtest="SandboxArchitectureTest" --batch-mode -q

All unit tests (2048 tests):

cd server/application-server && mvn test -Dsurefire.includedGroups="unit" -Dmaven.test.skip=false -DskipTests=false --batch-mode -q

Summary by CodeRabbit

  • Security
    • Enhanced sandbox security by expanding Git environment variable filtering to prevent arbitrary command execution and configuration overrides.
    • Added hardened Git security settings that disable hooks, prompts, editors, and external commands within the sandbox environment.

Copilot AI review requested due to automatic review settings March 24, 2026 18:19
@FelixTJDietrich
FelixTJDietrich requested a review from a team as a code owner March 24, 2026 18:19
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 78109832-a9a5-4821-880e-19bf744b5d15

📥 Commits

Reviewing files that changed from the base of the PR and between d4c56eb and 6ebc423.

📒 Files selected for processing (2)
  • server/application-server/src/main/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapter.java
  • server/application-server/src/test/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapterTest.java

📝 Walkthrough

Walkthrough

Security hardening of Git configuration injection in Docker sandbox environments. Expanded environment variable blocklists for Git-related code-execution vectors and reworked the buildEnvironment() method to unconditionally inject hardened Git security configurations via GIT_CONFIG_* environment variables, regardless of volume mount presence.

Changes

Cohort / File(s) Summary
Git Security Configuration Hardening
server/application-server/src/main/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapter.java
Expanded BLOCKED_ENV_VARS with Git-related variables (GIT_SSH*, GIT_ASKPASS, GIT_EDITOR, GIT_EXEC_PATH, GIT_TEMPLATE_DIR, GIT_EXTERNAL_DIFF, GIT_PROXY_COMMAND, GIT_SEQUENCE_EDITOR, GIT_PAGER, GIT_TERMINAL_PROMPT, GIT_ATTR_NOSYSTEM). Added GIT_CONFIG_ prefix to BLOCKED_ENV_PREFIXES. Introduced new GIT_SECURITY_CONFIGS constant with hardened key/value pairs for hook execution, prompts, editors, and proxy behavior. Reworked buildEnvironment() to unconditionally inject git security configs via GIT_CONFIG_* env vars with incremented indices, ensuring security values override user-provided configs.
Test Coverage Updates
server/application-server/src/test/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapterTest.java
Extended createSpec() helper with volumeMounts parameter. Updated git security config assertions to validate full GIT_SECURITY_CONFIGS set and verify correct GIT_CONFIG_* env var generation by index. Added tests for GIT_CONFIG_* prefix blocking. Replaced volume-specific tests with comprehensive assertions verifying security configs are present and hardened values (e.g., core.hooksPath=/nonexistent) are set correctly.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A bunny hops through Git's dark forest deep,
Blocking paths where secrets creep,
Config guards now stand so tall,
Safe from hooks and prompts' call,
Defense-in-depth—security wins the day! 🛡️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: blocking additional git code-execution vectors in DockerSandboxAdapter, which is the core focus of the PR.
Linked Issues check ✅ Passed The PR comprehensively addresses all requirements from issue #904: blocks 5+ git config vectors (core.sshCommand, credential.helper, diff.external, core.askPass, core.pager), applies hardening reliably regardless of volume mounts, and includes test coverage validating GIT_CONFIG_* environment variables.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the stated objectives. Expansions to BLOCKED_ENV_VARS and BLOCKED_ENV_PREFIXES, the new GIT_SECURITY_CONFIGS constant, and test updates are all necessary for the git security hardening feature and fully within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/application-server-block-additional-git-vectors

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot dosubot Bot added the bug Something isn't working label Mar 24, 2026
@github-actions github-actions Bot added application-server Spring Boot server: APIs, business logic, database size:L This PR changes 100-499 lines, ignoring generated files. labels Mar 24, 2026
Map<String, String> env = captor.getValue().environment();

// No volume mounts → COUNT equals security config count exactly
int count = Integer.parseInt(env.get("GIT_CONFIG_COUNT"));

Copilot AI 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.

Pull request overview

Hardens the Docker-based sandbox execution environment against additional Git configuration and environment-variable code execution vectors by enforcing a broader set of safe Git settings and ensuring they’re applied consistently even when repositories are cloned at runtime.

Changes:

  • Introduces a centralized GIT_SECURITY_CONFIGS list and injects it via GIT_CONFIG_* env vars (highest precedence) to neutralize multiple .git/config execution vectors.
  • Fixes a gating issue so Git security configs are injected regardless of whether volumeMounts are present (while still adding safe.directory only for mounts).
  • Extends environment variable blocklists to include Git execution-related vars and the GIT_CONFIG_ prefix; adds GIT_TERMINAL_PROMPT=0 and GIT_ATTR_NOSYSTEM=1.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
server/application-server/src/main/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapter.java Always injects hardened Git config env overrides; blocks additional Git env-based execution vectors; adds non-interactive/hardening Git env vars.
server/application-server/src/test/java/de/tum/in/www1/hephaestus/agent/sandbox/docker/DockerSandboxAdapterTest.java Adds unit tests validating Git security config injection behavior and new blocklist/prefix-block behavior.

Comment on lines +1022 to +1031
@Test
@DisplayName("should overwrite security env vars even if caller bypasses blocklist")
void shouldOverwriteSecurityEnvVarsViaOrdering() {
setupHappyPath();

// GIT_TERMINAL_PROMPT and GIT_ATTR_NOSYSTEM are in BLOCKED_ENV_VARS, so a caller
// can't inject them. This test verifies the defense-in-depth: even if they somehow
// leaked through, the security injection at the end of buildEnvironment() wins.
// We test this by verifying the final values are always the security-hardened ones.
sandboxAdapter.execute(createSpec());

Copilot AI Mar 24, 2026

Copy link

Choose a reason for hiding this comment

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

This test’s name/description claims to verify that security env vars “overwrite … even if caller bypasses blocklist”, but the test never injects conflicting caller-provided values (and the relevant keys are blocked anyway). As written it duplicates coverage from the other git-security tests and doesn’t actually validate the stated defense-in-depth behavior. Consider either (a) renaming/rewording the test to match what it asserts, or (b) reworking it to demonstrate an actual overwrite/collision scenario (e.g., for a non-blocked key that is intentionally overridden later in buildEnvironment).

Copilot uses AI. Check for mistakes.
…dboxAdapter

Closes #904

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@FelixTJDietrich
FelixTJDietrich force-pushed the fix/application-server-block-additional-git-vectors branch from 576ea04 to 6ebc423 Compare March 25, 2026 08:10
@FelixTJDietrich
FelixTJDietrich merged commit e5a15b2 into main Mar 25, 2026
40 checks passed
@FelixTJDietrich
FelixTJDietrich deleted the fix/application-server-block-additional-git-vectors branch March 25, 2026 08:36
@github-actions

Copy link
Copy Markdown
Contributor

📚 Documentation Preview

Preview has been removed (PR closed)

@FelixTJDietrich

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 0.51.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@FelixTJDietrich FelixTJDietrich added the released Included in a published release label Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

application-server Spring Boot server: APIs, business logic, database bug Something isn't working released Included in a published release size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(application-server): block additional git code-execution vectors in DockerSandboxAdapter

2 participants