Back to skill

Security audit

WorkbuddyOs

Security checks for vulnerabilities and agentic risk

Overview

This is a real WorkBuddy skinning tool, but its auto-install path persistently changes WorkBuddy startup and enables broad renderer debugging control.

Install only if you are comfortable with WorkBuddy being launched with a persistent local debugging port and with a LaunchAgent that automatically reinjects code. Prefer the one-shot apply/pause flow, avoid the auto-install scripts unless you explicitly need them, and verify that uninstall-auto.sh and uninstall-flag.sh fully remove the LaunchAgent and restore the original WorkBuddy executable.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

T06 · System Persistence

Error
Location
scripts/install-auto.sh:28
Finding

Persistent LaunchAgent Automatically Executes the Renderer Injection Pipeline

Content
View full analysis
"$PLIST" < Label${LABEL} ProgramArguments /bin/bash$ROOT/scripts/watch.local.sh RunAtLoad KeepAlive StandardOutPath$ROOT/scripts/watch.log StandardErrorPath$ROOT/scripts/watch.log EOF launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true launchctl bootstrap "gui/$(id -u)" "$PLIST" ``` From `scripts/watch.sh`: ```sh LAST_PID="" while true; do PID=$(pgrep -f "WorkBuddy.app/Contents/MacOS/Electron" | head -1) if [ -z "$PID" ]; then LAST_PID="" elif [ "$PID" != "$LAST_PID" ]; then if curl -s --max-time 1 "http://127.0.0.1:${PORT}/json/list" 2>/dev/null | grep -q "renderer/index.html"; then "$NODE" "$ROOT/src/apply.mjs" >>"$ROOT/scripts/watch.log" 2>&1 && LAST_PID=$PID fi fi sleep 2 done ``` ### Technical Analysis The installer creates `~/Library/LaunchAgents/com.workbuddy.skin.plist`, enables both `RunAtLoad` and `KeepAlive`, and immediately loads the service with `launchctl bootstrap`. The resulting process remains active across user sessions and repeatedly invokes `src/apply.mjs` when it detects a new WorkBuddy process. The LaunchAgent executes scripts directly from the project directory. Consequently, later modifications to `watch.local.sh`, `apply.mjs`, `inject.js`, or related payload files will be executed automatically under the logged-in user's accoun ...[truncated 1595 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/install-flag.sh:8
Finding

WorkBuddy Executable Is Replaced with a Persistent Debugging Wrapper

Content
View full analysis
&2; exit 1; } if [ -f "$BIN.real" ]; then exit 0 fi mv "$BIN" "$BIN.real" cat > "$BIN" <
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
tools/cdp.mjs:6
Finding

Fixed CDP Endpoint and General-Purpose Utility Permit Arbitrary WorkBuddy Renderer Execution

Content
View full analysis
| -f file'); process.exit(1); } const list = await (await fetch(`http://127.0.0.1:${PORT}/json/list`)).json(); const page = list.find(t => t.type === 'page' && t.url.includes('renderer/index.html')); if (!page) { console.error('renderer not found'); process.exit(1); } const ws = new WebSocket(page.webSocketDebuggerUrl); await new Promise((res, rej) => { ws.onopen = res; ws.onerror = rej; }); const result = await new Promise((resolve, reject) => { ws.onmessage = (ev) => { const msg = JSON.parse(ev.data); if (msg.id === 1) resolve(msg); }; ws.send(JSON.stringify({ id: 1, method: 'Runtime.evaluate', params: { expression: expr, returnByValue: true, awaitPromise: true }, })); setTimeout(() => reject(new Error('timeout')), 15000); }); ``` From `src/apply.mjs`: ```js spawn('open', ['-a', 'WorkBuddy', '--args', `--remote-debugging-port=${PORT}`], { detached: true, stdio: 'ignore' }).unref(); async function evaluate(page, expression) { const ws = new WebSocket(page.webSocketDebuggerUrl); await new Promise((res, rej) => { ws.onopen = res; ws.onerror = rej; }); const result = await new Promise((resolve, reject) => { ws.onmessage = ev => { const m = JSON.parse(ev.data); if (m.id === 1) resolve(m); }; ws.send(JSON.stringify({ id: 1, method: 'Runtime.evaluate', params: { expression, returnByValue: true } })); setTimeout(() => reject(new Error('evaluate timeout')) ...[truncated 2022 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (46)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script persistently replaces the app’s Electron binary with a wrapper that forces --remote-debugging-port=9223 on every launch. Chrome/Electron DevTools remote debugging can expose browser/session internals and, if reachable by other local users or bridged network access, can enable inspection or manipulation of app contents well beyond normal user expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The wrapper causes every future launch of the app to expose a remote debugging interface without a user-facing warning at the time of activation. Enabling this class of interface persistently expands the attack surface and may expose app data, session state, and script execution/inspection capabilities to unintended parties.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script ensures WorkBuddy is relaunched with a Chrome DevTools remote debugging port, then connects to that port and executes arbitrary JavaScript via Runtime.evaluate inside the app context. That gives the script full ability to alter UI, inspect app state, and potentially access privileged in-app data or trigger unintended actions; in a local desktop app context this is a strong code-injection capability far beyond a simple theming operation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script is explicitly designed to connect to a local Chrome DevTools Protocol endpoint, locate the WorkBuddy renderer, and execute attacker-supplied JavaScript via Runtime.evaluate. That creates arbitrary code execution inside the renderer context, which can access in-app state, DOM content, tokens, and potentially privileged bridges exposed by the app. The lack of any stated constrained purpose, allowlist, or safety boundary makes this dangerous in a skill context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly instructs users to install a persistent auto-injection mechanism, register a LaunchAgent, and modify the Electron startup path by renaming the original binary and inserting a forwarding wrapper with a remote debugging port. Even if intended only for theming, these steps weaken application and system integrity, create persistence, and normalize a technique that could be repurposed for unauthorized code injection or post-update breakage without clearly warning users about the security implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill explicitly instructs use of a CDP helper to execute arbitrary JavaScript in the WorkBuddy renderer while running the app in debug mode, but it does not clearly frame this as code execution against application state or explain the risks. In an agent setting, this can normalize unsafe execution patterns and could be repurposed to inspect sensitive data, alter app behavior, or perform unintended actions inside the desktop app context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The header comment says the script registers a LaunchAgent to auto-start watch.sh at login, but the generated plist also sets KeepAlive=true and redirects stdout/stderr into a persistent log file. That is a stronger, continuously running behavior with filesystem writes, which goes beyond the narrower wording of simple login auto-start.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

At this point the script creates a LaunchAgent plist that will be used to establish login-session persistence. In an installer, persistence is security-sensitive because it ensures continued execution of another script on future logins, increasing the blast radius if that watcher script is modified, compromised, or behaves unexpectedly.

Content

Scanner excerpt · scripts/install-auto.sh (reported line 29)May include surrounding context.

sh
chmod +x "$ROOT/scripts/watch.local.sh"

# 生成并加载 LaunchAgent
cat > "$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The installer immediately creates and loads a persistent LaunchAgent in the user session without an explicit confirmation step. In a skill/package context, silently establishing persistence reduces user awareness and can normalize autorun behavior, especially when paired with another script that will execute continuously at login.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

This is another trigger on the same plist-generation block and reflects the same persistence concern. The danger comes from automatic startup and continuous execution, not from the XML syntax itself.

Content

Scanner excerpt · scripts/install-auto.sh (reported line 31)May include surrounding context.

sh
# 生成并加载 LaunchAgent
cat > "$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>${LABEL}</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

This is another trigger on the same plist-generation block and reflects the same persistence concern. The danger comes from automatic startup and continuous execution, not from the XML syntax itself.

Content

Scanner excerpt · scripts/install-auto.sh (reported line 31)May include surrounding context.

sh
# 生成并加载 LaunchAgent
cat > "$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>${LABEL}</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The ProgramArguments entry binds launchd to execute the generated watch.local.sh automatically. This creates a durable autorun path for arbitrary future behavior in that script, which becomes more dangerous if the script can later be edited or replaced by another local process.

Content

Scanner excerpt · scripts/install-auto.sh (reported line 32)May include surrounding context.

sh
cat > "$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>${LABEL}</string>
  <key>ProgramArguments</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
96% confidence
Finding

This line actively loads the LaunchAgent into the user’s launchd session, making the persistence mechanism effective immediately. In the context of an installer for a cosmetic modification, silently activating autorun behavior materially increases risk because code will continue running outside the user’s immediate action and may be overlooked.

Content

Scanner excerpt · scripts/install-auto.sh (reported line 46)May include surrounding context.

sh
EOF

launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$PLIST"
echo "✓ 自动换肤已开启:今后正常打开 WorkBuddy 即可,皮肤会自动生效"
echo "· 日志:$ROOT/scripts/watch.log;卸载:scripts/uninstall-auto.sh"

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The comments explicitly describe making the debugging port effective for every launch method by renaming the original Electron executable and inserting a forwarding wrapper. That persistence mechanism is invasive because it alters the trusted application bundle and silently changes runtime behavior in a way users and administrators may not detect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script modifies an installed application under /Applications by moving the original executable and dropping in a replacement wrapper, but it provides no confirmation prompt before making the change. Silent modification of a signed app bundle can break trust assumptions, surprise users, and create a durable foothold for behavior they did not explicitly approve.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-auto.sh (reported line 8)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/uninstall-auto.sh (reported line 5)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/uninstall-auto.sh (reported line 7)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-auto.sh (reported line 8)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-auto.sh (reported line 42)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/uninstall-auto.sh (reported line 5)May include surrounding context.

sh
# uninstall-auto.sh — 关闭自动换肤
set -e
LABEL="com.workbuddy.skin"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
rm -f "$PLIST"
echo "✓ 自动换肤已关闭(当前皮肤仍在,WorkBuddy 重启后自然消失)"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This shell script deletes and replaces an application executable using rm -f and mv, which is a safety-critical file operation. Although it prints a success message afterward, there is no prior warning, confirmation prompt, or explanatory comment disclosing that the script will modify files inside /Applications and overwrite the current executable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations in natural-language content. The operational comments are written entirely in Chinese, with no indication that language choice is optional or justified by a region-specific constraint, which can impose a locale on maintainers or operators.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This shell script is a code file, so SQP-2 applies to safety-relevant operations such as subprocess execution. When the target app is detected, the script automatically runs apply.mjs and redirects all output to a log file, but there is no confirmation prompt, user-visible print/log message, or explanatory warning in the script about this automatic action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This script runs indefinitely, polls a local debugging-style HTTP endpoint, and automatically executes another script whenever it detects a matching renderer. That creates persistence and silent re-application behavior without user interaction in this file, which is risky because any compromise or unintended state change in the downstream apply script is repeatedly re-triggered.

Content

No source excerpt is available for this finding.