Summary
yapf-diff reads a unified diff from stdin and parses file paths from +++ b/path
lines without sanitization. An attacker who can supply the diff content
(e.g., via CI pipeline, git hooks, or redirected stdin) can inject path
traversal sequences such as +++ b/../../../etc/passwd, causing the script to open() and run yapf on arbitrary files.
Description
- Type: Path Traversal
- Source: Lines 83–86 in
third_party/yapf_third_party/yapf_diff/yapf_diff.py — filename extracted from sys.stdin via re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.prefix, line) without path validation.
- Sinks: Line 129:
open(filename); Lines 111–118: subprocess.Popen([args.binary, filename], ...).
- Impact: Read/write of arbitrary files when diff input is attacker-controlled (e.g., in CI using
git diff | yapf-diff -i).
Affected
PoC
- Create malicious diff with path traversal in
+++ line:
--- a/fake.py
+++ b/../../tmp/poc_victim.py
@@ -1,2 +1,2 @@
-def foo(): x=1
+def foo(): x = 1
-
Run: echo "<malicious_diff>" | yapf-diff --regex '.*'
-
The script will open and run yapf on ../../tmp/poc_victim.py (resolving to /tmp/poc_victim.py), demonstrating arbitrary path access.
Attack scenario
| Field |
Value |
| Severity |
High |
| CVSS 3.1 |
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N |
| CWE |
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') |
| Package |
yapf (Google) |
| Affected |
All versions prior to fix |
Primary Impact
Arbitrary file modification
With -i, yapf-diff writes changes to files. Path traversal can target arbitrary files for modification.
Code execution
subprocess.Popen([args.binary, filename], ...) runs yapf on the
chosen path. If an attacker can supply or influence args.binary, or if
the target file is crafted, this can lead to execution of
attacker-controlled code.
Summary
yapf-diff reads a unified diff from stdin and parses file paths from
+++ b/pathlines without sanitization. An attacker who can supply the diff content (e.g., via CI pipeline, git hooks, or redirected stdin) can inject path traversal sequences such as+++ b/../../../etc/passwd, causing the script toopen()and runyapfon arbitrary files.Description
third_party/yapf_third_party/yapf_diff/yapf_diff.py— filename extracted fromsys.stdinviare.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.prefix, line)without path validation.open(filename); Lines 111–118:subprocess.Popen([args.binary, filename], ...).git diff | yapf-diff -i).Affected
third_party/yapf_third_party/yapf_diff/yapf_diff.pyPoC
+++line:Run:
echo "<malicious_diff>" | yapf-diff --regex '.*'The script will open and run yapf on
../../tmp/poc_victim.py(resolving to/tmp/poc_victim.py), demonstrating arbitrary path access.Attack scenario
Primary Impact
Arbitrary file modification
With -i, yapf-diff writes changes to files. Path traversal can target arbitrary files for modification.
Code execution
subprocess.Popen([args.binary, filename], ...) runs yapf on the chosen path. If an attacker can supply or influence args.binary, or if the target file is crafted, this can lead to execution of attacker-controlled code.