b3ba9978cc42a5031c7b68e3cf917ec2e64643bc

Author
Marc Cornellà <hello@mcornella.com>
Committer
Marc Cornellà <hello@mcornella.com>
Date

Message

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
11 
12   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}
17 
18+  # 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 }
29 
30 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 }
37 
38 prompt_pygmalion_precmd(){
39-  setopt localoptions extendedglob
40+  setopt localoptions nopromptsubst extendedglob
41 
42   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}
47 
48-  PROMPT="${base_prompt}${gitinfo}${post_prompt}"
49+  PROMPT="${base_prompt}\$(git_prompt_info)${post_prompt}"
50 }
51 
52 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.