v3.5.2 — security hotfix #108
Security hotfix
This release fixes a local code execution vulnerability in tools/quota-statusline.sh reported in #108.
Affected versions: v3.5.0 and v3.5.1.
Affected configurations: users who wired tools/quota-statusline.sh into their CC statusLine (a setup the README explicitly recommends in v3.5.0+).
Severity: local code execution at user privilege, persistent re-fire on every CC statusline redraw, no user interaction beyond cd-ing into a hostile path on disk.
What was wrong
tools/quota-statusline.sh interpolated CC's hook stdin payload directly into a Python triple-quoted string literal:
input=$(cat)
result=$(python3 -c "
stdin_data = json.loads('''$input''') if '''$input''' else {}
")A ''' byte sequence anywhere in the payload closes the literal early and lets following bytes execute as Python in the user's CC process. CC's hook payload reflects user-controlled paths (cwd, workspace.current_dir, workspace.project_dir, transcript_path), and apostrophes are legal in filesystem paths. The realistic chain:
- Hostile directory name with
'''+payload+'''lands on disk (git clone, archive extract, npm package, etc.) - Victim has the recommended statusline wired up
- Victim
cds into a path matching the hostile name - CC fires the statusline hook on every redraw → arbitrary Python runs as the user
Fix
Capture stdin in bash, export CC_INPUT, and feed the Python source through a single-quoted heredoc (<<'PYEOF'). Single-quoting disables ALL bash interpolation inside the body. Python now reads the JSON via os.environ.get('CC_INPUT'), where the bytes are inert at every layer.
Two regression tests (T6, T7) drive the exact '''+__import__('os').system(...)+''' payload through the production script under a tmpdir-rooted HOME and assert the sentinel file is never created.
Upgrade
npm install -g claude-code-cache-fix@3.5.2If you've copied quota-statusline.sh into ~/.claude/hooks/ (per the README setup instructions), re-copy it from the upgraded package:
cp "$(npm root -g)/claude-code-cache-fix/tools/quota-statusline.sh" ~/.claude/hooks/If you wrote your own statusline based on the v3.5.0/v3.5.1 example, audit it for the json.loads('''$input''') pattern and replace with the heredoc + env var pattern. The fixed script in tools/quota-statusline.sh is the reference.
Credit
Reported responsibly by @schuay (Jakob Linke). Thank you.
Links
- Issue: #108
- Fix PR: #110
- CHANGELOG: v3.5.2 entry