From 38a1b613f10a162812ce91075bdf3ec102126dc1 Mon Sep 17 00:00:00 2001 From: Frank Terbeck Date: Sat, 25 Mar 2017 17:33:27 +0100 Subject: [PATCH] Handle volatile characters in prompts with promptsubst set MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit We don't set that option, but users may do it in .zshrc.local or similar. The issue is that performing expansions on a prompt string is an exploitable vulnerability, if you do not contol every part the prompt string is made up of. This is what is demonstrated by https://github.com/njhartwell/pw3nage Per default, the code strips [$`] from a final prompt string, so you can't really take advantage of prompt subst, even though you have it set. If the prompt_subst option is not set, the code does not kick in at all. If you want more control over which parts of the prompt are stripped, so you can take control of prompt_subst, you can do that as well. Here's an example that only strips the data returned from vcs_info: zstyle ':prompt:grml:*:items:vcs' strip-sensitive-characters on zstyle ':prompt:grml:*:setup' strip-sensitive-characters off Now you can take advantage of prompt_subst in privately defined tokens (even though I'd use a token that calls a function callback instead of inserting a string that relies on prompt_subst — but that's just me). Reported-by: Joerg Jaspert --- etc/zsh/zshrc | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index 6766615..4d9b9ad 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -2255,7 +2255,7 @@ grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name fi } -function grml_typeset_and_wrap () { +function grml_wrap_reply () { emulate -L zsh local target="$1" local new="$2" @@ -2263,14 +2263,16 @@ function grml_typeset_and_wrap () { local right="$4" if (( ${+parameters[$new]} )); then - typeset -g "${target}=${(P)target}${left}${(P)new}${right}" + REPLY="${left}${(P)new}${right}" + else + REPLY='' fi } function grml_prompt_addto () { emulate -L zsh local target="$1" - local lr it apre apost new v + local lr it apre apost new v REPLY local -a items shift @@ -2284,21 +2286,21 @@ function grml_prompt_addto () { || apost=${grml_prompt_post_default[$it]} zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" token new \ || new=${grml_prompt_token_default[$it]} - typeset -g "${target}=${(P)target}${apre}" if (( ${+grml_prompt_token_function[$it]} )); then ${grml_prompt_token_function[$it]} $it - typeset -g "${target}=${(P)target}${REPLY}" else case $it in battery) - grml_typeset_and_wrap $target $new '' '' + grml_wrap_reply $target $new '' '' ;; change-root) - grml_typeset_and_wrap $target $new '(' ')' + grml_wrap_reply $target $new '(' ')' ;; grml-chroot) if [[ -n ${(P)new} ]]; then - typeset -g "${target}=${(P)target}(CHROOT)" + REPLY="$CHROOT" + else + REPLY='' fi ;; vcs) @@ -2308,14 +2310,33 @@ function grml_prompt_addto () { vcscalled=1 fi if (( ${+parameters[$v]} )) && [[ -n "${(P)v}" ]]; then - typeset -g "${target}=${(P)target}${(P)v}" + REPLY="${(P)v}" + else + REPLY='' fi ;; - *) typeset -g "${target}=${(P)target}${new}" ;; + *) REPLY="$new" ;; esac fi - typeset -g "${target}=${(P)target}${apost}" + # Strip volatile characters per item. This is off by default. See the + # global stripping code a few lines below for details. + if [[ -o prompt_subst ]] && zstyle -t ":prompt:${grmltheme}:${lr}:items:$it" \ + strip-sensitive-characters + then + REPLY="${REPLY//[$\`]/}" + fi + typeset -g "${target}=${(P)target}${apre}${REPLY}${apost}" done + + # Per default, strip volatile characters (in the prompt_subst case) + # globally. If the option is off, the style has no effect. For more + # control, this can be turned off and stripping can be configured on a + # per-item basis (see above). + if [[ -o prompt_subst ]] && zstyle -T ":prompt:${grmltheme}:${lr}:setup" \ + strip-sensitive-characters + then + typeset -g "${target}=${${(P)target}//[$\`]/}" + fi } function prompt_grml_precmd () { -- 2.1.4