---
id: "CVE-2026-114096"
kind: "vulnerability"
aliases: ["CVE-2026-114096"]
title: "Dulwich: symlink following in checkout lets crafted repos plant hooks"
severity: "high"
cvss: 7.8
epss: 0.00155
exploited: false
status: "open"
category: "package"
products: []
ecosystems: []
tags: ["ci", "dulwich", "git-tooling", "package", "python"]
not_affected_if: ["trusted-repos-only", "version-1.2.8-or-later"]
published_at: "2026-10-21T01:17:34+00:00"
first_seen_at: "2026-10-23T21:57:28+00:00"
updated_at: "2026-10-25T03:08:27+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-114096", "first_seen_at": "2026-10-23T21:57:28+00:00"}, {"source": "epss", "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-114096", "first_seen_at": "2026-10-24T13:15:54+00:00"}]
---

# Dulwich: symlink following in checkout lets crafted repos plant hooks

Dulwich, a pure-Python Git implementation, follows a worktree symlink during porcelain.checkout(paths=[...]) because it opens files without O_NOFOLLOW. A crafted repository can point a symlink at .git/hooks/post-checkout, so restoring a file writes a malicious hook that runs code.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Run `pip show dulwich` (or check your lockfile) and see whether the version is between `0.24.0` and `1.2.8`.
- Find code that calls `porcelain.checkout` with a `paths=` argument on repositories you did not create.

## Fix

- Upgrade the dulwich package to `1.2.8` or later.
- Until upgraded, avoid calling `porcelain.checkout(paths=[...])` on untrusted repositories.

## Timeline

- 2026-10-23T21:57:28+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-114096
- 2026-10-24T13:15:54+00:00 epss https://api.first.org/data/v1/epss?cve=CVE-2026-114096

## From the sources

Dulwich from 0.24.0 before 1.2.8 contains a symlink following vulnerability in porcelain.checkout(paths=[...]) that allows attackers to write arbitrary files by abusing raw os.open without O_NOFOLLOW. Attackers can craft a repository where a worktree symlink points to .git/hooks/post-checkout, so restoring the file from a tag writes a malicious hook for code execution.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
