A proof-of-concept of a vulnerability in custom shell prompt scripts
github.com
github.com
[1]: https://github.com/git/git/blob/master/contrib/completion/gi...
[1]: https://github.com/git/git/blob/9d77b0405ce6b471cb5ce3a90436...
https://github.com/git/git/commit/8976500cbbb13270398d3b3e07...
git checkout complete_$(./foo)
If you hit Enter at this point without thinking you'll end up running './foo'. It should have expanded instead to something like git checkout 'complete_$(./foo)'
or git checkout complete_\$\(./foo\) git checkout <Tab>
git checkout $(./pwd) -% zsh -f
voi% echo $ZSH_VERSION
5.3.1
voi% autoload -U compinit
voi% compinit
voi% git checkout <tab><tab>\$\(./pw3n\)
Already on '$(./pw3n)'
Your branch is up-to-date with 'origin/$(./pw3n)'.
voi% git checkout com<tab>plete_\$\(./foo\)
Switched to branch 'complete_$(./foo)'Still not as worrisome to me as the full scripts that get executed by package managers when you install dependencies. Effectively every time you run something like "npm install" you're putting your faith in the entire tree of ancestor dependencies as any of them could have a pwnage script as a post install.
The is one of the primary reasons why I prefer distribution-packaged libraries to pulling a library and its dependencies directly from developers. Staleness is a small price to pay relative to having at least two sets of eyes glance over the source and not execute arbitrary build scripts on my system.
However, I currently use Fish shell myself and it seems to be safe: http://imgur.com/a/rjocA
bash-powerline is affected. I've sent out a PR: https://github.com/riobard/bash-powerline/pull/12/
My own fork (with some additional features) is already patched: https://github.com/Hexcles/bash-powerline
#!/bin/sh
prev_head=$1
new_head=$2
changing_branch=$3
REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null)"
if [ "$changing_branch" = 1 -a "$prev_head" = "0000000000000000000000000000000000000000" ]; then
new_head_name="$(git name-rev --name-only "$new_head"|sed -e 's|`|_|g' -e 's|$(|_|g')"
new_head_name_untaint="$(git name-rev --name-only "$new_head"|sed -e 's|`|x|g' -e 's|$(|x|g')"
if [ "$new_head_name" != "$new_head_name_untaint" ]; then
echo "
DANGER! INSECURE BRANCH NAME.
">&2
git name-rev --name-only "$new_head"
echo "
MOVING $REPO_DIR TO TRASH.
">&2
mkdir -p ~/.Trash
mv "$REPO_DIR" "$HOME/.Trash/${REPO_DIR##*/}.$(date +"%Y%m%d%H%M%S")"
fi
fiThis is a neat bug, though. Lots of package managers have similar problems, and I would not be surprised if there's a lot of git/shell/environment problems left to find.
Code quality is pretty much the reason though. The oh-my-zsh maintainer himself even wrote a post once upon a time about how not to run an OSS project.
Prezto forked the project and cleaned up everything quite nicely a long time ago.
git co -b foo <Tab> to complete branch names
git co -b foo $(./pw3n) <- execution right hereNow, I understand that you may not intimately understand 100% the code of the commands and shell extensions you use, but is that a "vulnerability"?
git cloning code vs. running code is sometimes a security boundary and sometimes not. For instance, if you go cd into that directory and then run make or ./configure or ./setup.py install or docker run or something, then yeah, you've removed that boundary. But in general, it's reasonable to keep the boundary there. Perhaps you're doing code review of code by an untrusted author, either of someone else's project or of a pull request to your own project. Perhaps you're packaging up the software to run it as a less-privileged account. Perhaps you're a sysadmin helping a user figure something out. And so forth.
Did you try creating a branch called "(./pw3n)" ?
I'm running fish with git-radar. I'm not vulnerable to that specific attack but to a similar one with the branch name (./pw3n)