From 38924282dbce92ff8f02bc0a82ff5906c5dc17d1 Mon Sep 17 00:00:00 2001 From: tomaioo Date: Sun, 26 Apr 2026 11:24:25 -0700 Subject: [PATCH 1/2] fix(security): 2 improvements across 2 files - Security: Command injection risk when exporting PATH in Zsh activation script - Security: Windows shell export does not escape values before emitting `set` commands Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- internal/shell/zsh.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/shell/zsh.go b/internal/shell/zsh.go index 0264b062..52186b0f 100644 --- a/internal/shell/zsh.go +++ b/internal/shell/zsh.go @@ -17,8 +17,6 @@ package shell import ( - "fmt" - "github.com/version-fox/vfox/internal/env" ) @@ -76,10 +74,6 @@ func (z zsh) Export(envs env.Vars) (out string) { } func (z zsh) export(key, value string) string { - // Use double quotes for PATH-like variables to avoid unnecessary ANSI-C quoting - if key == "PATH" { - return fmt.Sprintf("export %s=\"%s\";", key, value) - } return "export " + z.escape(key) + "=" + z.escape(value) + ";" } From e96377a4c98884d5ae46bebba285cdb9fdc2d00e Mon Sep 17 00:00:00 2001 From: tomaioo Date: Sun, 26 Apr 2026 11:24:25 -0700 Subject: [PATCH 2/2] fix(security): 2 improvements across 2 files - Security: Command injection risk when exporting PATH in Zsh activation script - Security: Windows shell export does not escape values before emitting `set` commands Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- internal/shell/clink.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/shell/clink.go b/internal/shell/clink.go index a5c212fe..42f17cba 100644 --- a/internal/shell/clink.go +++ b/internal/shell/clink.go @@ -18,6 +18,7 @@ package shell import ( "fmt" + "strings" "github.com/version-fox/vfox/internal/env" ) @@ -48,5 +49,16 @@ func (b clink) Export(envs env.Vars) (out string) { } func (b clink) set(key, value string) string { - return fmt.Sprintf("set \"%s=%s\"\n", key, value) + return fmt.Sprintf("set \"%s=%s\"\n", escapeCmdSet(key), escapeCmdSet(value)) +} + +func escapeCmdSet(value string) string { + value = strings.ReplaceAll(value, "\r", " ") + value = strings.ReplaceAll(value, "\n", " ") + return strings.NewReplacer( + "^", "^^", + "\"", "^\"", + "%", "%%", + "!", "^!", + ).Replace(value) }