fix(themes): fix potential command injection in `pygmalion`, `pygmalion-virtualenv` and `refined`
The pygmalion and pygmalion-virtualenv themes unsafely handle git prompt information
which results in a double evaluation of this information, so a malicious git repository
could trigger a command injection if the user cloned and entered the repository.
A similar method could be used in the refined theme. All themes have been patched against this
vulnerability.
Diff
1diff --git a/themes/pygmalion-virtualenv.zsh-theme b/themes/pygmalion-virtualenv.zsh-theme
2index 47b0b4fb14a82174236a4c5813bc2aaeaf011881..c2ab7f4e637bb03987c710065a638e835b99369d 100644
3--- a/themes/pygmalion-virtualenv.zsh-theme
4+++ b/themes/pygmalion-virtualenv.zsh-theme
5@@ -35,19 +35,20 @@ prompt_setup_pygmalion(){
6 }
7 8 prompt_pygmalion_precmd(){
9- setopt localoptions extendedglob
10+ setopt localoptions nopromptsubst extendedglob
1112 local gitinfo=$(git_prompt_info)
13 local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
14- local exp_nocolor="$(print -P \"$base_prompt_nocolor$gitinfo_nocolor$post_prompt_nocolor\")"
15+ local exp_nocolor="$(print -P \"${base_prompt_nocolor}${gitinfo_nocolor}${post_prompt_nocolor}\")"
16 local prompt_length=${#exp_nocolor}
1718+ # add new line on prompt longer than 40 characters
19 local nl=""
20-
21 if [[ $prompt_length -gt 40 ]]; then
22- nl=$'\n%{\r%}';
23+ nl=$'\n%{\r%}'
24 fi
25- PROMPT="$base_prompt$gitinfo$nl$post_prompt"
26+
27+ PROMPT="${base_prompt}\$(git_prompt_info)${nl}${post_prompt}"
28 }
2930 prompt_setup_pygmalion
31diff --git a/themes/pygmalion.zsh-theme b/themes/pygmalion.zsh-theme
32index b13adfd5fb79d39cfb3c389be7dae68b9df5eb4d..be9ca38895882ea4e1b6be2061105c2783dea8d7 100644
33--- a/themes/pygmalion.zsh-theme
34+++ b/themes/pygmalion.zsh-theme
35@@ -19,14 +19,14 @@ prompt_setup_pygmalion(){
36 }
3738 prompt_pygmalion_precmd(){
39- setopt localoptions extendedglob
40+ setopt localoptions nopromptsubst extendedglob
4142 local gitinfo=$(git_prompt_info)
43 local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
44- local exp_nocolor="$(print -P \"$base_prompt_nocolor$gitinfo_nocolor$post_prompt_nocolor\")"
45+ local exp_nocolor="$(print -P \"${base_prompt_nocolor}${gitinfo_nocolor}${post_prompt_nocolor}\")"
46 local prompt_length=${#exp_nocolor}
4748- PROMPT="${base_prompt}${gitinfo}${post_prompt}"
49+ PROMPT="${base_prompt}\$(git_prompt_info)${post_prompt}"
50 }
5152 prompt_setup_pygmalion
53diff --git a/themes/refined.zsh-theme b/themes/refined.zsh-theme
54index 5d39bd757491b232e7974cddb52c291725e6cf22..5e2de7a87fb95e57ea83add4d3a2297afcc3f9ee 100644
55--- a/themes/refined.zsh-theme
56+++ b/themes/refined.zsh-theme
57@@ -70,6 +70,7 @@ preexec() {
58 # Output additional information about paths, repos and exec time
59 #
60 precmd() {
61+ setopt localoptions nopromptsubst
62 vcs_info # Get version control info before we start outputting stuff
63 print -P "\n$(repo_information) %F{yellow}$(cmd_exec_time)%f"
64 unset cmd_timestamp #Reset cmd exec time.