gstack-upgrade
“Upgrade gstack to the latest version.”
migrations
aipkg.jsonLICENSE.txtmigrations/v0.15.2.0.shmigrations/v0.16.2.0.shmigrations/v1.0.0.0.shmigrations/v1.1.3.0.shmigrations/v1.17.0.0.shmigrations/v1.27.0.0.shmigrations/v1.37.0.0.shmigrations/v1.38.1.0.shmigrations/v1.40.0.0.shREADME.mdSKILL.mdSKILL.md.tmpl- 01LP3MCP Least Privilege85%MEDIUM
SKILL.md:1
detailhide
The skill declares Bash capability but does not explicitly declare it in a permissions section. This creates ambiguity about what the skill is authorized to do and makes it harder for users to understand the security implications of granting Bash access. Bash commands can execute arbitrary operations on the system.
1---2name: gstack-upgrade3version: 1.1.0fix Add an explicit 'permissions' or 'requires' section to the SKILL.md frontmatter clearly declaring all shell capabilities and the scope of system modifications (e.g., file system changes, git operations, home directory writes).
- 02TP4MCP Tool Poisoning90%HIGH
SKILL.md:1
detailhide
The skill's declared purpose is to 'Upgrade gstack to the latest version' but the actual code performs extensive system modifications far beyond a simple version upgrade: modifying directory structures, running migrations, executing git commits/pushes, modifying configuration files with jq, managing gitignore and other dot files, invoking external binaries, and prompting users about unrelated topics like writing preferences. This is a severe behavioral mismatch that violates the principle of least surprise.
1---2name: gstack-upgrade3version: 1.1.0fix Refactor the skill to separate concerns: (1) Create a dedicated upgrade-only skill with clear, limited scope; (2) Move configuration management, migrations, and system restructuring into separate, explicitly-named skills; (3) Update the description to accurately reflect all actual behaviors or break the skill into smaller, focused components with honest documentation.
- 03SDI-188%MEDIUM
SKILL.md:128
detailhide
The skill modifies local git repositories and configuration (gitignore, git-tracked directories) well beyond the scope of a version upgrade. Operations like 'git rm -r --cached' and removing vendored copies alter the repository state and user's project structure in ways not implied by 'upgrade gstack'.
126Use the install type and directory detected in Step 2:127128**For git installs** (global-git, local-git):129```bash130cd "$INSTALL_DIR"fix Restrict the skill to upgrading only the gstack tool itself. Extract repository and configuration management into separate, explicitly-scoped skills. If these operations are necessary, require explicit user confirmation before modifying .gitignore or removing tracked directories.
- 04SDI-287%MEDIUM
SKILL.md:169
detailhide
This section performs destructive file system operations (rm -rf, git rm) and modifies git repository state without adequate user warning or granular confirmation. The operations alter the user's project structure and git history in ways that could cause data loss or confusion.
167168**If `LOCAL_GSTACK` is non-empty AND `TEAM_MODE` is `true`:** Remove the vendored copy. Team mode uses the global install as the single source of truth.169170```bash171cd "$_ROOT"fix Add explicit pre-execution warnings before any destructive operation. Require per-operation confirmation (not just a single yes/no at the start). Consider creating backups before rm -rf operations and offer a rollback mechanism.
- 05SQP-280%MEDIUM
SKILL.md:73
detailhide
File write operations (e.g., writing .gitignore, setting configuration values) lack explicit user confirmation or prominent warnings. Users may not realize their project files or home directory configuration is being modified.
71_NEW_LEVEL=$((_CUR_LEVEL + 1))72[ "$_NEW_LEVEL" -gt 3 ] && _NEW_LEVEL=373echo "$_REMOTE_VER $_NEW_LEVEL $(date +%s)" > "$_SNOOZE_FILE"74```75Note: `{new}` is the remote version from the `UPGRADE_AVAILABLE` output — substitute it from the update check result.fix Add confirmation dialogs or warnings before any write operation. Log what files will be modified and ask for approval. Provide clear before/after diffs when modifying existing files.
- 06SQP-292%HIGH
SKILL.md:133
detailhide
Destructive shell operations like 'git reset --hard' and 'rm -rf' with backup cleanup can cause permanent data loss if the upgrade fails or is interrupted. The skill description does not prominently warn users about these destructive operations, and the backup removal step ('rm -rf "$INSTALL_DIR.bak"') means there is no recovery path if something goes wrong.
131STASH_OUTPUT=$(git stash 2>&1)132git fetch origin133git reset --hard origin/main134./setup135```fix Add a prominent warning in the skill description about destructive operations. Implement atomic transactions where possible. Keep backups for a longer period (at least one user session). Require explicit confirmation before running 'git reset --hard'. Consider a dry-run mode first.
- 07SQP-275%MEDIUM
SKILL.md.tmpl:70
detailhide
The skill writes configuration state files (~/.gstack/update-snoozed, ~/.gstack/config.yaml) without explicit user confirmation or disclosure. While the file write itself is preceded by AskUserQuestion, the subsequent silent state writes to user's home directory lack transparency. This violates the principle that file modifications should be clearly disclosed to the user.
68_NEW_LEVEL=$((_CUR_LEVEL + 1))69[ "$_NEW_LEVEL" -gt 3 ] && _NEW_LEVEL=370echo "$_REMOTE_VER $_NEW_LEVEL $(date +%s)" > "$_SNOOZE_FILE"71```72Note: `{new}` is the remote version from the `UPGRADE_AVAILABLE` output — substitute it from the update check result.fix Add explicit logging/confirmation before each file write operation. For snooze state writes, inform the user: 'Saving snooze state to ~/.gstack/update-snoozed'. For config writes, confirm the action with AskUserQuestion before writing to gstack-config. Ensure all file paths and changes are visible in the skill output.
- 08SQP-285%HIGH
SKILL.md.tmpl:143
detailhide
Multiple destructive rm -rf operations (rm -rf "$INSTALL_DIR.bak", rm -rf "$LOCAL_GSTACK.bak", rm -rf "$LOCAL_GSTACK/.git") lack adequate warning or user confirmation. If variables are unset or miscalculated, these could delete unintended directories. The skill performs recursive deletion of entire directory trees without confirming the paths with the user first.
141mv "$TMP_DIR/gstack" "$INSTALL_DIR"142cd "$INSTALL_DIR" && ./setup143rm -rf "$INSTALL_DIR.bak" "$TMP_DIR"144```145fix Before each rm -rf, print the full resolved path and ask for confirmation via AskUserQuestion or at least log prominently: 'About to delete: [full-path]'. Consider requiring explicit user approval for destructive operations. Use safer patterns like creating backups in isolated temp directories or using git operations instead of raw deletion.
- 09SQP-280%MEDIUM
SKILL.md.tmpl:139
detailhide
The skill performs a network operation (git clone from github.com/garrytan/gstack.git) without explicit security warning or verification. Users may not realize they're fetching code from the internet, and there is no checksum verification or signature validation. This creates supply-chain attack risk if the repository is compromised.
137PARENT=$(dirname "$INSTALL_DIR")138TMP_DIR=$(mktemp -d)139git clone --depth 1 https://github.com/garrytan/gstack.git "$TMP_DIR/gstack"140mv "$INSTALL_DIR" "$INSTALL_DIR.bak"141mv "$TMP_DIR/gstack" "$INSTALL_DIR"fix Add explicit warning to skill description: 'This skill downloads gstack source code from GitHub.' Implement cryptographic verification (checksums or GPG signatures) for downloaded content. Display the git URL and commit hash to the user before proceeding. Consider pinning to a specific release tag rather than cloning latest.
- 10SQP-270%MEDIUM
migrations/v1.40.0.0.sh:50
detailhide
The migration script modifies critical user configuration files (.brain-allowlist, .brain-privacy-map.json, .gitattributes) without explicit user confirmation or interactive prompts. Users triggering 'gstack-upgrade' may not be aware their configs will be silently modified. While warnings are logged to stderr, there is no pre-flight summary, confirmation dialog, or dry-run capability before mutations occur. This violates user consent best practices for invasive file modifications.
48 if ! grep -Fq -- "${PATTERN}" "${ALLOWLIST}" 2>/dev/null; then49 if grep -q '^# ---- USER ADDITIONS BELOW' "${ALLOWLIST}" 2>/dev/null; then50 if sed -i.bak "/^# ---- USER ADDITIONS BELOW/i\\51${PATTERN}52" "${ALLOWLIST}" 2>/dev/null; thenfix Implement a pre-flight check phase that: (1) lists all files and patterns that will be modified, (2) shows a summary to the user before proceeding, (3) provides a --dry-run flag to preview changes without applying them, (4) optionally requires explicit --yes flag or interactive confirmation before modifying any user configs.
- 11RA2Session Persistence75%MEDIUM
SKILL.md:12
detailhide
The skill declares Write capability, which allows it to persistently modify the user's home directory and configuration files. This broad permission combined with the lack of explicit constraints creates a session persistence risk where the skill can leave behind state that affects future sessions or tools.
allowed-tools: - Bash - Read - Write - AskUserQuestion --- <!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->fix Restrict Write permissions to only necessary files (e.g., a specific ~/.gstack/upgrade-state directory). Audit all Write operations to ensure they are necessary and temporary where possible. Remove stale state files proactively.
- 12RA2Session Persistence78%MEDIUM
SKILL.md:59
detailhide
The skill writes persistent snooze state to the user's home directory without clear user consent. This creates hidden state that silences upgrade notifications, potentially leaving the system vulnerable if the skill should be upgraded for security reasons. Users may not realize their upgrade notifications have been snoozed.
``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. **If "Not now":** Write snooze state with escalating backoff (first snooze = 24h, second = 48h, third+ = 1 week), then continue with the current skill. Do not mention the upgrade again. ```bash _SNOOZE_FILE="$HOME/.gstack/update-snoozed" _REMOTE_VER="{new}"fix Require explicit confirmation before writing snooze state. Display a clear message to the user explaining that the snooze file has been created and how to restore notifications. Consider storing snooze state in a more visible location or use a configuration file that users can easily inspect.
- 13RA2Session Persistence72%MEDIUM
SKILL.md:223
detailhide
The skill writes upgrade marker files and clears update check caches without explicit user consent. This modifies the user's home directory state in ways that could interfere with other tools or processes monitoring upgrade status. The clearing of 'update-snoozed' could re-enable notifications unexpectedly.
`v{VERSION}.sh` and runs only when upgrading from an older version. See CONTRIBUTING.md for how to add new migrations. ### Step 5: Write marker + clear cache ```bash mkdir -p ~/.gstackfix Document all home directory modifications and their purpose. Require user confirmation before writing state files. Consider storing this metadata in a skill-specific state store rather than scattered home directory files.
- 14RA2Session Persistence70%MEDIUM
SKILL.md.tmpl:56
detailhide
The snooze state writing mechanism persists data (.gstack/update-snoozed) with escalating backoff logic, but the file format and logic are not validated. A malformed snoozed file could cause parsing errors or skip upgrades indefinitely. Additionally, the snooze logic uses simple string comparison for version matching, which could fail with complex version schemes.
``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. **If "Not now":** Write snooze state with escalating backoff (first snooze = 24h, second = 48h, third+ = 1 week), then continue with the current skill. Do not mention the upgrade again. ```bash _SNOOZE_FILE="$HOME/.gstack/update-snoozed" _REMOTE_VER="{new}"fix Add input validation for version numbers before writing to snooze file. Use a structured format (JSON or INI) instead of space-separated fields. Add safeguards to ensure snooze entries expire after the final backoff level (1 week max). Log snooze state changes to help users understand when reminders will reappear.
- 15RA2Session Persistence65%MEDIUM
SKILL.md.tmpl:220
detailhide
Writing marker files (~/.gstack/just-upgraded-from) and clearing cache files without validation could leave stale state if operations fail partially. If the upgrade succeeds partially but Step 5 fails, the marker file may indicate success when the upgrade is incomplete, causing downstream skills to assume a valid upgrade.
`v{VERSION}.sh` and runs only when upgrading from an older version. See CONTRIBUTING.md for how to add new migrations. ### Step 5: Write marker + clear cache ```bash mkdir -p ~/.gstackfix Wrap Step 5 file operations in error handling. Only write the just-upgraded-from marker after ALL upgrade steps complete successfully. Use a temporary marker file and rename atomically. Validate file writes completed before proceeding to Step 6.
- 16TM1Tool Parameter Abuse86%HIGH
SKILL.md:172
detailhide
The command 'git rm -r --cached .claude/skills/gstack/' removes files from git tracking without explicit per-file confirmation. Combined with modifications to .gitignore, this can silently alter the user's project structure and version control state. The error suppression ('2>/dev/null || true') hides failures.
```bash cd "$_ROOT" git rm -r --cached .claude/skills/gstack/ 2>/dev/null || true if ! grep -qF '.claude/skills/gstack/' .gitignore 2>/dev/null; then echo '.claude/skills/gstack/' >> .gitignore fifix Require explicit user confirmation before removing files from git tracking. Show the user the list of files to be removed. Log all git operations with clear output. Remove the error suppression to ensure users see any problems that occur.
- 17TM1Tool Parameter Abuse88%HIGH
SKILL.md:184
detailhide
The recursive removal 'rm -rf "$LOCAL_GSTACK.bak"' permanently deletes backup files after a sync operation. If the sync or subsequent setup fails silently, the backup is already gone and unrecoverable. This violates safe upgrade practices.
```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" rm -rf "$LOCAL_GSTACK/.git" cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ```fix Keep backups for at least one full upgrade cycle or one week. Only remove old backups after explicit user confirmation or a successful verification step. Warn users before deleting backups.
- 18TM1Tool Parameter Abuse80%HIGH
SKILL.md:228
detailhide
The command 'rm -f ~/.gstack/last-update-check' silently deletes update check state without user visibility. This could interfere with other tools monitoring gstack's update status and leaves no audit trail.
```bash mkdir -p ~/.gstack echo "$OLD_VERSION" > ~/.gstack/just-upgraded-from rm -f ~/.gstack/last-update-check rm -f ~/.gstack/update-snoozed ```fix Only remove state files after successful upgrade completion. Log what files are being deleted and provide the user with visibility. Consider archiving old state rather than deleting it.
- 19TM1Tool Parameter Abuse80%HIGH
SKILL.md:229
detailhide
The command 'rm -f ~/.gstack/update-snoozed' silently clears snooze state, which could unexpectedly re-enable upgrade notifications or interfere with user preferences set during a previous session.
mkdir -p ~/.gstack echo "$OLD_VERSION" > ~/.gstack/just-upgraded-from rm -f ~/.gstack/last-update-check rm -f ~/.gstack/update-snoozed ``` ### Step 6: Show What's Newfix Preserve user snooze preferences across upgrades. Only clear snooze state with explicit user confirmation. Log snooze state changes for auditability.
- 20TM1Tool Parameter Abuse90%HIGH
SKILL.md:133
detailhide
'git reset --hard origin/main' discards all local changes to the gstack repository without backup or confirmation. If executed during an upgrade of a locally-modified gstack (e.g., a developer's custom version), all work is permanently lost. This is an irreversible destructive operation.
cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main ./setup ``` If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them."fix Add a confirmation step that lists what local changes will be lost. Offer to stash changes automatically. Require explicit user approval before executing git reset --hard. Consider running git reset --hard in a safer mode (e.g., with a backup first).
- 21TM1Tool Parameter Abuse80%HIGH
SKILL.md.tmpl:169
detailhide
The git rm -r --cached command removes files from git index without user confirmation. If .claude/skills/gstack is miscalculated or contains important files, this could remove tracked content from version control. The 2>/dev/null suppression hides errors from the user.
```bash cd "$_ROOT" git rm -r --cached .claude/skills/gstack/ 2>/dev/null || true if ! grep -qF '.claude/skills/gstack/' .gitignore 2>/dev/null; then echo '.claude/skills/gstack/' >> .gitignore fifix Display the git rm command and its target to the user before executing. Require AskUserQuestion confirmation for git rm operations. Do not suppress stderr; let users see warnings. Consider using git rm with --dry-run first to show what would be deleted.
- 22TM1Tool Parameter Abuse85%HIGH
SKILL.md.tmpl:181
detailhide
The rm -rf "$LOCAL_GSTACK/.git" and rm -rf "$LOCAL_GSTACK.bak" commands delete entire directory trees without confirming the resolved paths. If $LOCAL_GSTACK is empty or points to an unexpected location, this could delete critical user data. The skill assumes these variables are always correct without validation.
```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" rm -rf "$LOCAL_GSTACK/.git" cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ```fix Add explicit path validation before deletion. Print the full resolved path (using readlink or pwd -P) and require user confirmation via AskUserQuestion. Use a safer approach: mv to a quarantine directory instead of immediate deletion. Add post-delete verification to confirm the directory was actually removed.
- 23TM1Tool Parameter Abuse75%HIGH
SKILL.md.tmpl:225
detailhide
The rm -f commands in Step 5 delete cache/marker files without validation. While these are metadata files in ~/.gstack/, if the paths are miscalculated or if an attacker can control the HOME variable, unintended files could be deleted. The rm -f suppresses errors, hiding failures.
```bash mkdir -p ~/.gstack echo "$OLD_VERSION" > ~/.gstack/just-upgraded-from rm -f ~/.gstack/last-update-check rm -f ~/.gstack/update-snoozed ```fix Validate file paths exist before deletion. Use explicit if [ -f "$file" ] checks before rm. Log which files are being deleted. Consider using safer patterns: truncate files to zero bytes instead of deleting, or use git to track config state instead of manual file operations.
- 24TM1Tool Parameter Abuse85%HIGH
SKILL.md.tmpl:130
detailhide
The git reset --hard origin/main command performs a destructive reset of the local git repository without user confirmation. This overwrites any uncommitted changes in the gstack directory. If the user has unsaved local modifications, they will be lost silently (only a stash warning is shown after the fact). This is particularly dangerous if executed during auto-upgrade.
cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main ./setup ``` If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them."fix Require explicit user confirmation (AskUserQuestion) before running git reset --hard. Warn the user: 'This will discard uncommitted changes in [directory]'. Consider using git reset --soft or git clean -n (dry-run) first to show what will be lost. Store the stash output before reset and only proceed if user acknowledges the warning.