Know every vulnerabilitybefore it knows you.
DevGuard continuously monitors your dependencies and alerts you when CVEs like this one affect your stack — with real-time threat intelligence built for developers.
GHSA-fjr4-x663-mwxc
No affected components available
Summary
Diffable.diff() forwards **kwargs straight into diff/diff_tree with no check_unsafe_options guard. Diffable is mixed into Commit, Tree, IndexFile, and Submodule, giving a broad surface. git diff --output=<path> writes real patch content to an attacker-chosen path, enabling arbitrary file overwrite.
Root Cause
diff.py:188-283 builds and runs the diff command with no check_unsafe_options anywhere in the method (grep-confirmed). Additionally diff.py:265 does args.insert(0, other), placing the caller-supplied other ref BEFORE the -- separator, so a value of --output=/path is parsed by git as an option — a value-only control path requiring no kwarg key.
Impact
Overwrite/corrupt any file at process privilege with attacker-chosen path (e.g. ~/.ssh/authorized_keys, configs, lockfiles). Content is real diff/patch bytes (attacker-influenced). Per the skill's rule, controlling WHICH file is overwritten = I:H regardless of content constraints.
Proof of Concept
# Key-control:
commit.diff(other_commit, output='/home/app/.ssh/authorized_keys') # victim overwritten with diff (105 bytes verified)
# Value-control (attacker controls only the ref string):
commit.diff(other='--output=/home/app/.ssh/authorized_keys') # 14-byte victim -> 146 bytes of diff-tree output
Attack Chain
- Entry (value-control):
commit.diff(other=<user ref>)withother = "--output=/home/app/.ssh/authorized_keys". Guard: none inDiffable.diff. Bypass proof: nocheck_unsafe_optionsin the method body (grep);otherinserted pre---at diff.py:265. - Sink:
git diff-tree <sha> --output=/home/app/.ssh/authorized_keys -r ...-> git opens+truncates the target then writes diff content. Impact: overwrite/corrupt any file at process privilege (attacker chooses the path). Verified argv and victim overwrite live.
Bypass Evidence
Live-verified on HEAD (tag 3.1.53): both key-control (output=) and value-control (other='--output=...') overwrote a victim file with real diff-tree content; argv confirmed ['git','diff-tree','<sha>','--output=/victim','-r',...]. This is the same value-control model GHSA-956x deemed fix-worthy for iter_commits(rev='--output=') — but diff is a distinct, unguarded sink NOT touched by that fix.
Affected Versions
<= 3.1.53
Suggested Fix
Add check_unsafe_options to Diffable.diff (mirroring iter_commits/archive), and/or place --end-of-options before the other ref so it cannot be parsed as an option.
Reported by zx (Jace) — GitHub: @manus-use
The vulnerability can be exploited over the network without needing physical access. It is easy for an attacker to exploit this vulnerability. An attacker needs basic access or low-level privileges. No user interaction is needed for the attacker to exploit this vulnerability. The impact is confined to the system where the vulnerability exists. There is a high impact on the integrity of the data. There is a high impact on the availability of the system.
Exploitation activity has been observed. Apply available patches or mitigations urgently.
Probability that this vulnerability will be exploited in the wild within the next 30 days.
We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database.
Browse More
Continuously monitor your dependencies and get alerted when vulnerabilities like this one affect your stack.
Checkout DevGuard