Summary
A path traversal vulnerability in Dulwich's commit filtering logic can cause files to be written outside the intended working directory when symlinks persist across commits.
A repository crafted with a redirecting symlink may enable unauthorized file modification, including placement of files in Git hook locations that could lead to code execution when those hooks run.
A path traversal vulnerability in Dulwich's commit filtering logic can cause files to be written outside the intended working directory when symlinks persist across commits.
A repository crafted with a redirecting symlink may enable unauthorized file modification, including placement of files in Git hook locations that could lead to code execution when those hooks run.
Affected context
The vulnerability occurs in Dulwich versions using CommitFilter._apply_index_filter() during branch filtering. It becomes risky when a repository contains symlinks that persist between commits and the filtering process writes descendant-commit files without sufficiently constraining resolved paths to the working directory.
The vulnerability occurs in Dulwich versions using CommitFilter._apply_index_filter() during branch filtering. It becomes risky when a repository contains symlinks that persist between commits and the filtering process writes descendant-commit files without sufficiently constraining resolved paths to the working directory.
Exploit preconditions
- Attack surface: Repository processing during branch filtering or related commit transformation operations
- Required access: Ability to provide or cause processing of a crafted repository
- Trigger point: File writes performed by
CommitFilter._apply_index_filter() - Why exploitation is possible: A symlink from an ancestor commit can redirect later file writes outside the intended working directory
- Additional condition: The destination must be writable by the process, and code execution depends on a written file being subsequently treated as executable, such as a Git hook
- Attack surface: Repository processing during branch filtering or related commit transformation operations
- Required access: Ability to provide or cause processing of a crafted repository
- Trigger point: File writes performed by
CommitFilter._apply_index_filter() - Why exploitation is possible: A symlink from an ancestor commit can redirect later file writes outside the intended working directory
- Additional condition: The destination must be writable by the process, and code execution depends on a written file being subsequently treated as executable, such as a Git hook
Why this happens
The underlying bug is insufficient validation of filesystem paths after repository state changes involving symlinks. File operations performed during commit filtering can follow a symlink established by an earlier commit rather than enforcing that the resolved destination remains within the designated working directory.
This maps to CWE-22: Improper Limitation of a Pathname to a Restricted Directory, because attacker-influenced repository content can redirect writes beyond the intended path boundary.
The underlying bug is insufficient validation of filesystem paths after repository state changes involving symlinks. File operations performed during commit filtering can follow a symlink established by an earlier commit rather than enforcing that the resolved destination remains within the designated working directory.
This maps to CWE-22: Improper Limitation of a Pathname to a Restricted Directory, because attacker-influenced repository content can redirect writes beyond the intended path boundary.
Potential impact
- An attacker may write or overwrite files outside the working directory
- Repository metadata or operational files could be modified
- Files in Git hook locations could be created or replaced
- Code could execute when a modified hook is later invoked
- Build, deployment, or source-processing workflows could be compromised
- Integrity of generated files and repository contents could be affected
- An attacker may write or overwrite files outside the working directory
- Repository metadata or operational files could be modified
- Files in Git hook locations could be created or replaced
- Code could execute when a modified hook is later invoked
- Build, deployment, or source-processing workflows could be compromised
- Integrity of generated files and repository contents could be affected
General mitigation guidance
Mitigation typically focuses on enforcing destination boundaries for every filesystem write, including after symlink resolution.
Common defensive patterns include:
- Resolve and canonicalize destination paths before writing
- Verify that resolved paths remain beneath an approved working-directory root
- Treat repository symlinks as untrusted input during filtering operations
- Reject or isolate symlink-based paths when the workflow does not require them
- Use filesystem APIs and policies that prevent writes through unexpected links
- Run repository processing with least privilege and without unnecessary write access to hooks, metadata, or deployment paths
- Prefer isolated temporary workspaces with narrowly scoped permissions
Mitigation typically focuses on enforcing destination boundaries for every filesystem write, including after symlink resolution.
Common defensive patterns include:
- Resolve and canonicalize destination paths before writing
- Verify that resolved paths remain beneath an approved working-directory root
- Treat repository symlinks as untrusted input during filtering operations
- Reject or isolate symlink-based paths when the workflow does not require them
- Use filesystem APIs and policies that prevent writes through unexpected links
- Run repository processing with least privilege and without unnecessary write access to hooks, metadata, or deployment paths
- Prefer isolated temporary workspaces with narrowly scoped permissions
How teams detect issues like this
Organizations commonly detect this class of issue through:
- Static analysis for file writes that concatenate repository paths without canonical containment checks
- Code review of symlink handling across multi-commit or multi-stage workflows
- Tests that place symlinks in ancestor states and verify resolved writes remain inside the workspace
- Runtime monitoring for unexpected writes to Git metadata, hook directories, or paths outside approved workspaces
- Policy enforcement that restricts repository-processing jobs from modifying executable or deployment-controlled locations
- Automated security review tools that flag path normalization and symlink-resolution gaps
Organizations commonly detect this class of issue through:
- Static analysis for file writes that concatenate repository paths without canonical containment checks
- Code review of symlink handling across multi-commit or multi-stage workflows
- Tests that place symlinks in ancestor states and verify resolved writes remain inside the workspace
- Runtime monitoring for unexpected writes to Git metadata, hook directories, or paths outside approved workspaces
- Policy enforcement that restricts repository-processing jobs from modifying executable or deployment-controlled locations
- Automated security review tools that flag path normalization and symlink-resolution gaps

