From 684eee291bb72da6b749b26134a94a3b6f0969b9 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 2 Jun 2026 21:32:08 -0700 Subject: [PATCH] fix(gstack-slug): sanitize cached slug before eval The compute and fallback paths filter slug output to [a-zA-Z0-9._-], but a value read straight from ~/.gstack/slug-cache was echoed into eval output unsanitized. A locally-planted cache file could inject shell into eval "$(gstack-slug)". Re-sanitize on every path so the invariant the file header promises actually holds, and heal a poisoned cache on the next write. Co-Authored-By: Claude Opus 4.8 (1M context) --- bin/gstack-slug | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bin/gstack-slug b/bin/gstack-slug index 6b853b6d7..24bbca4f1 100755 --- a/bin/gstack-slug +++ b/bin/gstack-slug @@ -31,6 +31,14 @@ fi # 3. Fallback to basename only when there's truly no git remote configured SLUG="${SLUG:-$(basename "$PWD" | tr -cd 'a-zA-Z0-9._-')}" +# 3b. Re-sanitize unconditionally before the value is echoed into `eval`/`source` +# output. The compute (2) and fallback (3) paths already filter, but a value +# read straight from the cache file (1) does NOT — a poisoned +# ~/.gstack/slug-cache/ would otherwise inject shell into +# `eval "$(gstack-slug)"`. Filtering here honors the [a-zA-Z0-9._-] invariant +# promised in the header on every path, and heals a poisoned cache on write (4). +SLUG=$(printf '%s' "$SLUG" | tr -cd 'a-zA-Z0-9._-') + # 4. Cache the slug for future sessions (atomic write, fail silently) if [[ -n "$SLUG" ]]; then mkdir -p "$CACHE_DIR" 2>/dev/null || true