GHSA-5fqc-mrg8-w798: Path Traversal

Published Oct 2, 2026
·
Updated

Summary

Dulwich's filterbranch.py CommitFilter.applyindexfilter() is vulnerable to symlink directory traversal. When processing commit history, materialized tree entries (including symlinks) persist in the working directory between commits, allowing a symlink from an ancestor commit to redirect file writes from a descendant commit to arbitrary filesystem locations.

Root Cause

applyindexfilter() at dulwich/filterbranch.py:212 calls buildindexfromtree(".", tmpindexpath, ...) which materializes all tree entries to the current working directory. The finally block (line 229-230) only cleans up the temporary index file (os.unlink(tmpindexpath)) — NOT the filesystem files written to CWD. When processcommit() processes parents recursively first (line 260), files materialized from ancestor commits persist and affect processing of descendant commits.

On dulwich 1.2.7, buildfilefromblob() has no symlink protection, and validatepathelement only validates name patterns, not filesystem state.

Impact

An attacker can craft a malicious repository where running filterbranch with an index filter writes attacker-controlled content to arbitrary filesystem locations via symlink traversal. This achieves RCE if the write targets .git/hooks/.

Attack Scenario

1. Attacker creates a repository where commit history (linearized) has: - Ancestor commit: tree entry evil (mode 120000, symlink → /targetdir) - Descendant commit: tree entry evil/payload (mode 100644, attacker content) 2. Victim clones repository and runs filterbranch with an index filter 3. processcommit() processes ancestor first → materializes evil as symlink to /targetdir in CWD 4. CWD is NOT cleaned between commits 5. Processing descendant: os.path.exists("./evil") → True (symlink exists). buildfilefromblob(blob, mode, "./evil/payload") → open("./evil/payload", "wb") follows intermediate symlink → writes to /targetdir/payload

Suggested Fix

Clean the CWD between commit iterations in applyindexfilter(), or verify that no intermediate path components are symlinks before writing files.

Reported by zx (Jace)

Affected Software

1 affected componentFixes available
pip/dulwich>=0.23.1<=1.2.7
1.2.8

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/dulwich to a version that resolves this vulnerability.

    Fixed in 1.2.8
  2. Compensating control

    In dulwich's filter_branch.py, clean the current working directory between commit iterations in _apply_index_filter(), or verify that no intermediate path components are symlinks before writing files.

Event History

Oct 2, 2026
Advisory Published
via GitHub·06:53 PM
Data Sourced
via GitHub·06:53 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Who is exposed to this issue?

Users are exposed when they run Dulwich's filter_branch functionality with an index filter against a repository an attacker can craft or influence. The vulnerable processing materializes repository tree entries into the current working directory.

2

What does an attacker need to exploit it?

An attacker needs to provide a malicious repository history containing a symlink in an ancestor commit and content written in a descendant commit. They must also induce a user to run filter_branch with an index filter on that repository.

3

What can the attacker do if exploitation succeeds?

The persisted symlink can redirect writes from a later commit to arbitrary filesystem locations. This can result in attacker-controlled file contents being written outside the intended working directory, with high confidentiality, integrity, and availability impact.

4

How can I tell whether my workflow is affected?

Dulwich 1.2.7 is identified as lacking symlink protection in build_file_from_blob(). Review whether your automation or users invoke filter_branch with index filters, especially when handling untrusted repository histories.

5

What can I do before updating?

Do not run filter_branch index filters on untrusted repositories. If processing cannot be avoided, perform it in an isolated, disposable environment where filesystem writes cannot affect sensitive host files.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203