Skip to content

Sanitize shell interpolations to prevent injection#75

Open
zmanian wants to merge 1 commit intomcintyre94:mainfrom
zmanian:fix/shell-injection-safety
Open

Sanitize shell interpolations to prevent injection#75
zmanian wants to merge 1 commit intomcintyre94:mainfrom
zmanian:fix/shell-injection-safety

Conversation

@zmanian
Copy link
Contributor

@zmanian zmanian commented Mar 14, 2026

Summary

  • Adds a shellEscape() utility that wraps values in single quotes with proper escaping
  • Applies it to all shell command construction in ChatViewModel (workingDirectory, tokens, sessionId, MCP config paths, prompts, git name/email, custom instructions)
  • Applies it to SpriteOverviewViewModel (GitHub token auth, Sprites CLI token auth)
  • Adds sanitizedSessionId() to ClaudeQuestionTool that strips non-alphanumeric characters from sessionId before using it in file paths and JSON

Previously, workingDirectory, sessionId, configPath, and tokens were interpolated directly into shell commands without escaping. While exploitation risk is low (values come from controlled sources), defense-in-depth is warranted for shell command construction.

Test plan

  • Verify chat messaging still works end-to-end (send message, receive response)
  • Verify MCP question tool installs and works
  • Verify GitHub and Sprites CLI auth from overview screen
  • Verify git name/email with special characters (e.g., apostrophes) works

Generated with Claude Code

Add a shellEscape() helper for safe single-quote wrapping and
apply it to all shell command construction sites:
- ChatViewModel: workingDirectory, tokens, sessionId, MCP config
- SpriteOverviewViewModel: GitHub and Sprites CLI token auth
- ClaudeQuestionTool: validate sessionId chars in file paths/JSON

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant