Back to skill

Security audit

workbuddy-multi-machine-sync

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to sync WorkBuddy across machines, but its setup and daemon create high-impact risks around persistent remote code execution, plaintext GitHub token storage, and possible local data loss.

Review carefully before installing. Do not use the curl-to-bash command, do not embed a live GitHub token in the setup script, and do not allow plaintext ~/.git-credentials storage unless you accept that exposure. Treat anyone with write access to the sync repository as able to change code that runs on every synced machine. Back up ~/.workbuddy first, prefer SSH or OS keychain credentials, pin and inspect setup scripts, and require manual review for conflicts instead of automatic remote-wins resolution.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:151
Finding

Unverified Remote Setup Script Is Piped Directly into Bash

Content
View full analysis
" \ "https://raw.githubusercontent.com//wb-sync/main/wb-setup-machine.sh" | bash ``` ### Technical Analysis The documented installation procedure downloads a shell script from a mutable GitHub branch and pipes the response directly into Bash. The downloaded content is not pinned to an immutable commit and is not verified using a cryptographic hash or signature. Transport encryption and the authorization header only protect transport and repository access. They do not protect users if the repository, maintainer account, token, branch, or hosted script is compromised. The user also has no opportunity to inspect the exact payload before execution. Because the URL references `main`, the effective code executed by this command can change after the Skill itself has been reviewed. ### Attack Path 1. An attacker compromises the GitHub repository, a maintainer account, or a token with repository write access. 2. The attacker modifies `wb-setup-machine.sh` on the `main` branch to include a malicious payload. 3. A user follows the installation instructions in `SKILL.md`. 4. `curl` retrieves the attacker-controlled version of the script. 5. Bash executes the response immediately with the permissions of the current user. 6. The payload can access user files, alter shell configuration, steal locally available credentials, or install additional persistence. ### Impact Assessment Successful exploitation provides arbitrary code execution under the account running the command. This normally includes access to the user's WorkBuddy configuration, synchronized data, Git credentials, shell startup files, and any other resources accessible to that user. The impact extends to every machine on which a user follows the docume ...[truncated 175 chars]
Remediation
View remediation
/wb-sync//wb-setup-machine.sh" printf '%s %s\n' '' 'wb-setup-machine.sh' | shasum -a 256 -c - less wb-setup-machine.sh bash wb-setup-machine.sh ``` ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/auto-sync-multi.sh:40
Finding

Synchronized Scripts Create a Persistent Remote-Code Execution Channel

Content
View full analysis
/dev/null 2>&1 PULL_EXIT=$? ``` The daemon repeatedly executes a script located inside that synchronized directory: ```bash if [ -z "$PYTHON" ]; then # No Python available, use pure bash background mode nohup /bin/bash -c " while true; do /bin/bash '$WB_DIR/auto-sync.sh' 2>/dev/null sleep 300 done " >/dev/null 2>&1 & echo $! > "$PID_FILE" exit 0 fi # Use Python start_new_session=True for a true daemon "$PYTHON" -c " import subprocess, os wb = os.path.expanduser('~/.workbuddy') proc = subprocess.Popen( ['/bin/bash', '-c', \"while true; do /bin/bash '\" + wb + \"/auto-sync.sh' 2>/dev/null; sleep 300; done\"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, start_new_session=True ) with open(wb + '/.sync-daemon.pid', 'w') as f: f.write(str(proc.pid)) " 2>/dev/null ``` The setup process adds shell startup hooks that restart the daemon and execute the synchronized script: ```bash # WorkBuddy auto-sync — daemon keepalive + sync on terminal open if [ -f ~/.workbuddy/start-sync-daemon.sh ]; then bash ~/.workbuddy/start-sync-daemon.sh 2>/dev/null fi if [ -t 1 ] && [ -f ~/.workbuddy/auto-sync.sh ]; then _wb_now=$(date +%s) _wb_last=$(cat ~/.workbuddy/.last-auto-sync 2>/dev/null || echo 0) if [ $((_wb_now - _wb_last)) -gt 300 ]; then bash ~/.workbuddy/auto-sync.sh >/dev/null 2>&1 & echo $_wb_now > ~/.workbuddy/.last-auto-sync fi unset _wb_now _wb_last fi ``` The ...[truncated 2193 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup-machine.sh.template:25
Finding

GitHub Token Is Stored in Plaintext and Embedded in the Setup Script

Content
View full analysis
" REMOTE_URL="" GITHUB_USERNAME="" GITHUB_TOKEN="" BRANCH="main" ``` ```bash # === Step 4: Store credentials (GitHub only) === if [ "$REMOTE_NAME" = "origin" ] && [ -n "$GITHUB_TOKEN" ]; then echo "https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com" > "$HOME/.git-credentials" chmod 600 "$HOME/.git-credentials" git config --global credential.helper store echo ">> GitHub credentials stored" fi ``` ### Technical Analysis The documented workflow requires replacing a token placeholder in the setup script, leaving the secret embedded in the script itself. The script then writes the same token into `~/.git-credentials` using Git's plaintext `store` credential helper. File mode `0600` limits access to the current account but does not encrypt the credential. Any process or attacker with access to the account can read it. The setup script may also be copied, backed up, shared, or uploaded while still containing the token. The use of `>` overwrites the entire existing `~/.git-credentials` file, potentially deleting unrelated credentials. Configuring `credential.helper store` globally also weakens credential handling for other Git repositories used by the account. ### Attack Path 1. A user replaces `` in the template with a live token. 2. The completed setup script remains on disk or is transferred to another machine. 3. The script writes the token into `~/.git-credentials` as part of a plaintext URL. 4. An attacker gains local user-level file access, accesses a backup, or obtains an accidentally shared copy of the setup script. 5. The attacker extracts the token. 6. The attacker authenticates to GitHub and performs oper ...[truncated 745 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auto-sync-multi.sh:45
Finding

Destructive Reset and Conflict Handling Can Irrecoverably Discard Local Data

Content
View full analysis
> Backing up existing config to $BACKUP_DIR ..." mkdir -p "$BACKUP_DIR" for f in SOUL.md IDENTITY.md USER.md MEMORY.md mcp.json settings.json skills; do if [ -e "$WB_DIR/$f" ]; then cp -r "$WB_DIR/$f" "$BACKUP_DIR/" fi done ``` It then performs a hard reset against the remote branch: ```bash git fetch "$REMOTE_NAME" git reset --hard "$REMOTE_NAME/$BRANCH" ``` Automatic conflict handling discards one side and deletes the recovery stash: ```bash if [ $PULL_EXIT -ne 0 ]; then # Rebase conflict — stash, pull, pop git rebase --abort 2>/dev/null git stash >/dev/null 2>&1 git pull "$REMOTE" "$BRANCH" >/dev/null 2>&1 git stash pop >/dev/null 2>&1 if [ $? -ne 0 ]; then # Stash pop conflict — keep remote, log conflict git checkout --theirs . 2>/dev/null git stash drop >/dev/null 2>&1 echo "[${TS}] CONFLICT on $(hostname) — kept remote version" >> "$CONFLICT_LOG" tail -50 "$CONFLICT_LOG" > "$CONFLICT_LOG.tmp" && mv "$CONFLICT_LOG.tmp" "$CONFLICT_LOG" 2>/dev/null fi fi ``` ### Technical Analysis The backup runs only if `SOUL.md` or `MEMORY.md` exists and copies only a fixed subset of files. Other tracked configuration and untracked data in `~/.workbuddy` may not be preserved. `git reset --hard` then replaces tracked working-tree content with the remote branch state. During regular synchronization, failed stash application causes the script to select the remote side with `git checkout --theirs .` and then delete the stash. The log records only that a confli ...[truncated 1703 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code chunk only manages launching a persistent background loop for auto-sync execution and storing a PID file. While this could be a supporting part of a sync system, it does not implement or expose most of the specific multi-machine features claimed in the description, such as backend configuration, machine registry, conflict resolution, commit tagging, stale lock detection, or status reporting. The code’s actual purpose is much narrower: starting a sync daemon.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill directs users to download and immediately execute a remote script via curl piped to bash. This gives the remote content full code execution on the host without inspection, and if the repository, transport, token usage, or referenced script is compromised, an attacker can run arbitrary commands and steal local data or credentials.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

Using a shell pipeline into bash is a classic dangerous chaining pattern because it converts downloaded network content directly into executed commands. In a configuration-sync skill, this is especially risky since users may grant repository tokens and operate on sensitive local config directories, magnifying the impact of compromise.

Content

Scanner excerpt · SKILL.md (reported line 168)May include surrounding context.

bash
# For GitHub backend:
curl -sSL -H "Authorization: token <TOKEN>" \
  "https://raw.githubusercontent.com/<USER>/wb-sync/main/wb-setup-machine.sh" | bash

# For iCloud backend:
bash wb-setup-machine.sh  # after AirDrop or manual copy

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A GitHub token is written in plaintext to a persistent credentials file without a clear warning or consent step. This creates long-lived secret exposure on disk and increases the chance of accidental leakage through backups, local compromise, or other tooling reading the file.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The script handles and persists a GitHub token in ~/.git-credentials, creating a direct credential exposure path. Even if intended for convenience, storing reusable credentials in plaintext increases the blast radius of workstation compromise and can enable unauthorized repository access.

Content

Scanner excerpt · scripts/setup-machine.sh.template (reported line 82)May include surrounding context.

text
# === Step 4: Store credentials (GitHub only) ===
if [ "$REMOTE_NAME" = "origin" ] && [ -n "$GITHUB_TOKEN" ]; then
  echo "https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com" > "$HOME/.git-credentials"
  chmod 600 "$HOME/.git-credentials"
  git config --global credential.helper store
  echo ">> GitHub credentials stored"

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The credential file path plus global credential helper configuration causes persistent reuse of stored GitHub secrets by git. This is more dangerous in this skill because the script is intended for multi-machine rollout, so the insecure pattern may be replicated across several Macs and normalizes weak secret handling.

Content

Scanner excerpt · scripts/setup-machine.sh.template (reported line 83)May include surrounding context.

text
# === Step 4: Store credentials (GitHub only) ===
if [ "$REMOTE_NAME" = "origin" ] && [ -n "$GITHUB_TOKEN" ]; then
  echo "https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com" > "$HOME/.git-credentials"
  chmod 600 "$HOME/.git-credentials"
  git config --global credential.helper store
  echo ">> GitHub credentials stored"
fi

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The existing ~/.workbuddy git repository is forcibly reset to the remote branch with 'git reset --hard', which discards uncommitted local changes without confirmation. In a setup script that also switches remotes, this can destroy local configuration or replace trusted local content with remote-controlled content unexpectedly.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

Using 'git reset --hard' on a user config directory gives a remote-controlled branch the ability to overwrite local state and erase changes immediately. In this skill's context, the remote repository is the sync source, so misuse or compromise of that source can propagate destructive changes across multiple machines.

Content

Scanner excerpt · scripts/setup-machine.sh.template (reported line 98)May include surrounding context.

text
git remote remove icloud 2>/dev/null || true
  git remote add "$REMOTE_NAME" "$REMOTE_URL"
  git fetch "$REMOTE_NAME"
  git reset --hard "$REMOTE_NAME/$BRANCH"
else
  echo ">> Initializing git and pulling from remote..."
  git init

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs users to write files under ~/.workbuddy and execute multiple shell commands, but it declares no explicit tool scope or permissions boundary. That omission weakens reviewability and increases the chance an agent or user applies the skill with broader filesystem/shell access than expected.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

Step 2: Initialize Machine Registry

bash
# Create machines.json with this machine registered
MACHINE_NAME=$(cat ~/.workbuddy/.machine-name)
HOSTNAME=$(hostname)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The profile modifications cause code to run on every terminal startup, including daemon launching and background sync behavior. Persistent shell hooks expand execution beyond a one-time setup task and can create surprising, hard-to-audit behavior, especially if the synced files or scripts are later modified by a remote source.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document presents remote code execution as normal setup flow without any warning, verification step, or trust guidance. That omission materially increases the likelihood users will run unreviewed code containing malicious or compromised changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script is designed to run automatically every 5 minutes and perform pulls, rebases, stashes, commits, and pushes silently, with output redirected away from the user. In the context of a tool that syncs configuration across multiple machines, silent network and file-modifying behavior increases the risk of unnoticed data loss, unintended propagation of local changes, and hard-to-audit repository state changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script modifies the user's global Git identity and default branch settings, which affects all repositories on the machine rather than only the WorkBuddy sync repository. This is an over-broad side effect that can silently alter unrelated developer workflows, attribution, and automation, making it a legitimate security and integrity concern even if not overtly malicious.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Changing global Git configuration without any user-facing disclosure creates hidden persistent side effects beyond the skill's stated purpose. Because the modification is silent and occurs inside an auto-sync script, users may not realize their system-wide Git identity has been overwritten until it affects unrelated repositories or published commits.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/setup-machine.sh.template (reported line 12)May include surrounding context.

text
#   <GITHUB_TOKEN>    → GitHub token (only for GitHub backend)
#
# Usage (on any new machine):
#   1. Install WorkBuddy, launch once, then quit (to create ~/.workbuddy/)
#   2. Run: bash wb-setup-machine.sh
#
# The script will:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script persists a GitHub username/token pair in plaintext to ~/.git-credentials and enables the global 'store' credential helper. This broadens access beyond the immediate setup task because any later git/github operation on the machine may reuse or expose the token, and compromise of the user account reveals the secret directly.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/setup-machine.sh.template (reported line 83)May include surrounding context.

text
# === Step 4: Store credentials (GitHub only) ===
if [ "$REMOTE_NAME" = "origin" ] && [ -n "$GITHUB_TOKEN" ]; then
  echo "https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com" > "$HOME/.git-credentials"
  chmod 600 "$HOME/.git-credentials"
  git config --global credential.helper store
  echo ">> GitHub credentials stored"
fi

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script appends aliases and auto-executes sync/daemon scripts from the user's shell profile, causing code in ~/.workbuddy to run on future terminal launches. Because that directory is populated from a remote git repository, a compromised or malicious repo can achieve persistent code execution whenever the shell starts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script silently modifies the user's shell profile to add aliases and run background sync scripts on terminal open. This changes future shell behavior and creates persistence without an explicit approval step, which is especially risky because the executed scripts live in a remotely synced directory.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/start-sync-daemon.sh (reported line 37)May include surrounding context.

sh
if [ -z "$PYTHON" ]; then
  # No Python available, use pure bash background mode
  nohup /bin/bash -c "
    while true; do
      /bin/bash '$WB_DIR/auto-sync.sh' 2>/dev/null
      sleep 300

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This script silently launches a persistent background process using nohup and repeatedly executes auto-sync.sh every 5 minutes, but provides no user-facing output, prompt, or explanatory disclosure in the script body. Because it starts a surviving daemon and writes a PID file while suppressing all output, users may not realize a persistent process has been created.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The Python branch uses subprocess.Popen with start_new_session=True to detach a long-running shell loop and suppresses stdin/stdout/stderr, but does not display any warning or confirmation to the user. This is a safety-relevant subprocess operation because it creates a durable background daemon that continues running after the terminal closes.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Fetching an external script at runtime introduces a supply-chain risk because the reviewed skill behavior can change independently of the reviewed SKILL.md. In this case the fetched script is then executed immediately, making any compromise of the hosting location or referenced path directly lead to arbitrary code execution.

Content

Scanner excerpt · SKILL.md (reported line 167)May include surrounding context.

bash
# For GitHub backend:
curl -sSL -H "Authorization: token <TOKEN>" \
  "https://raw.githubusercontent.com/<USER>/wb-sync/main/wb-setup-machine.sh" | bash

# For iCloud backend:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file provides a command that permanently changes the user's shell profile by appending an alias, but it does not warn the user that their login shell configuration will be modified. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or system integrity; persistent shell-profile edits merit at least a brief disclosure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.