Back to skill

Security audit

Apple Watch Health Sync

Security checks for vulnerabilities and agentic risk

Overview

This Apple Watch sync skill has a plausible purpose, but it handles sensitive health data with overbroad persistence, network exposure, and weak secret controls.

Review this skill carefully before installing. It is intended to sync Apple Watch health data, but it creates a long-running local service, exposes health records on the LAN if reachable, duplicates the API key in several places, and asks the agent to handle that key directly. Only use it if you are comfortable hardening the server first: bind to localhost unless LAN access is required, avoid persistent elevated startup tasks, do not share .env.json or templates containing the key, and review or remove the mutable upstream download path.

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
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (6)

T06 · System Persistence

Error
Location
SKILL.md:33
Finding

Persistent Health Server Registered with Unnecessary Elevated Privileges

Content
View full analysis
" $trigger = New-ScheduledTaskTrigger -AtLogon Register-ScheduledTask -TaskName "HealthSyncServer" -Action $action -Trigger $trigger -RunLevel Highest -Force Start-ScheduledTask -TaskName "HealthSyncServer" ``` ```xml ProgramArguments python3server.py WorkingDirectoryHEALTH_SYNC_DIR RunAtLoad KeepAlive ``` ```bash launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist ``` ### Technical Analysis The Skill instructs the Agent to register the generated server as a Windows scheduled task or macOS LaunchAgent. Both mechanisms survive the Skill execution and future Agent sessions. Continuous background operation is relevant to the declared real-time synchronization functionality. However, the Windows task uses `-RunLevel Highest`, even though a Flask server listening on an unprivileged port and writing to the user's project directory does not require administrative execution. This exceeds the minimum privileges necessary. The service runs `server.py` using relative executable and script references. If the script, working directory, or resolved Python executable is replaced or compromised, attacker-controlled code will execute automatically at subsequent logons. On Windows, it may execute with the task's elevated privileges. ### Attack Path 1. The user or Agent follows the setup instructions. 2. A scheduled task or LaunchAgent is installed and configured to run at logon and remain active. 3. An attacker gains write access to `server.py`, its working directory, or a dependency ...[truncated 647 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.py:307
Finding

Unauthenticated Dashboard Exposes the API Key and Protected Health Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.py:403
Finding

API Credential Stored and Distributed Through Multiple Plaintext or Reversible Channels

Content
View full analysis
.env.json") return config ``` The credential is Base64-encoded and inserted into generated templates: ```python def make_template(name, data_type, lan_ip, api_key): headers_b64 = base64.b64encode(json.dumps([{"api-key": api_key}]).encode()).decode() return { "includeSymptoms": False, "notifyOnUpdate": True, "workoutTypes": [], "metrics": data_type["metrics"], "headers": headers_b64, "urlString": f"http://{lan_ip}:{PORT}/api/data", } ``` The key is also printed directly: ```python print(f" API Key: {api_key}") ``` ```python print(f" 3. IMPORTANT: manually add API key header after import:") print(f" Open automation -> Headers -> Add Header") print(f" Key: api-key") print(f" Value: {api_key}") ``` The Skill instructions additionally state: ```markdown Read the API key from .env.json first - you will need to tell the user. SEND THE FILE TO USER. ``` ### Technical Analysis Base64 is an encoding format and provides no confidentiality. Anyone who obtains a generated template can decode the `headers` value and recover the API key. The same credential is duplicated across `.env.json`, dashboard content, generated phone templates, terminal output, and potentially chat or file-transfer history. Duplication substantially i ...[truncated 1445 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/setup.py:31
Finding

Unpinned Dependencies and Unverified Mutable Upstream Download

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.py:187
Finding

ZIP Extraction Allows Writes Outside the Intended Upstream Directory

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:75
Finding

Setup Instructions Forcibly Terminate Unrelated Processes on Port 3001

Content
View full analysis
/dev/null ``` ### Technical Analysis The instructions terminate every process listening on port 3001 without verifying the process identity, executable path, owner, or relationship to this Skill. Both variants use forceful termination, and the Unix command sends `SIGKILL`, preventing the target process from performing cleanup. A port conflict does not establish that the listening process is an obsolete Health Sync server. It may be an unrelated user application or service. The instruction therefore exceeds what is necessary to start the declared server safely. ### Attack Path 1. A legitimate application or service is listening on port 3001. 2. The Agent follows the Skill's setup instructions. 3. The command identifies the owning process solely by its listening port. 4. The process is forcibly terminated without user confirmation. 5. The unrelated application becomes unavailable and may lose buffered or in-progress data. ### Impact Assessment The issue can cause local denial of service, interruption of unrelated applications, and data corruption caused by abrupt process termination. If the command is executed with elevated privileges, it may also terminate services owned by other users or the system, depending on operating-system controls. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (37)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Run `python scripts/setup.py` - generates server, dashboard, API key, and phone templates.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Run `python scripts/setup.py` - generates server, dashboard, API key, and phone templates.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Run `python scripts/setup.py` - generates server, dashboard, API key, and phone templates.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly instructs the agent to read a secret from .env.json and disclose it to the user in chat/setup messages. Even if intended for legitimate configuration, extracting and transmitting secrets from local files violates safe secret-handling practices and can leak credentials through conversation history, screenshots, or compromised messaging channels.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/setup.py (reported line 175)May include surrounding context.

python
if has_git:
        print(f"  git clone -> upstream/")
        env = os.environ.copy()
        for k in ["https_proxy", "http_proxy", "HTTPS_PROXY", "HTTP_PROXY"]:
            env.pop(k, None)
        result = subprocess.run(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requests only a binary prerequisite in metadata while the instructions clearly require broad capabilities including shell execution, file read/write, environment access, and network operations. This creates an undeclared privilege surface that reduces reviewability and can let an agent perform sensitive actions without explicit scope constraints.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The skill instructs the agent to install a persistent startup task so the server runs independently across sessions and logons. Persistence is a sensitive behavior because it survives the current interaction and can continue processing data or expose services long after the user expects the agent's actions to end.

Content

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

The server MUST run independently of any agent session. Do NOT start it in an exec session that will get killed by heartbeat or session recycling.

Windows - register as a startup task:

powershell
$action = New-ScheduledTaskAction -Execute "pythonw.exe" -Argument "server.py" -WorkingDirectory "<health-sync-dir>"
$trigger = New-ScheduledTaskTrigger -AtLogon

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The launchd plist instructions set up a persistent agent that restarts automatically and survives reboot/logon. Installing persistence mechanisms is security-sensitive because it changes the user's system state beyond the immediate task and can maintain ongoing access to health data.

Content

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

Start-ScheduledTask -TaskName "HealthSyncServer"

text

**macOS** - use launchd plist:
```bash
cat > ~/Library/LaunchAgents/com.health-sync.server.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The plist creation content is part of a persistent autorun configuration. Even if operationally useful, embedding autorun installation in a skill normalizes durable execution without strong guardrails or explicit consent flows.

Content

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

macOS - use launchd plist:

bash
cat > ~/Library/LaunchAgents/com.health-sync.server.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">

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

This portion continues the persistent launch agent configuration, including keepalive behavior that will respawn the service. Keepalive increases persistence strength and can make shutdown harder, which is risky for services processing private health information.

Content

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

bash
cat > ~/Library/LaunchAgents/com.health-sync.server.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>com.health-sync.server</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

This portion continues the persistent launch agent configuration, including keepalive behavior that will respawn the service. Keepalive increases persistence strength and can make shutdown harder, which is risky for services processing private health information.

Content

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

bash
cat > ~/Library/LaunchAgents/com.health-sync.server.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>com.health-sync.server</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The ProgramArguments and related launch agent directives operationalize automatic background execution of the server. Such persistence is not inherently malicious here, but it is security-relevant because it creates enduring process execution and a listening service.

Content

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

md
cat > ~/Library/LaunchAgents/com.health-sync.server.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>com.health-sync.server</string>
  <key>ProgramArguments</key><array>

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

The completion of the plist plus log paths finalizes a persistent service installation. Persistent logging of a health sync service may also increase secondary exposure if logs contain sensitive request or error details.

Content

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

md
<key>StandardOutPath</key><string>HEALTH_SYNC_DIR/server.log</string>
  <key>StandardErrorPath</key><string>HEALTH_SYNC_DIR/server.log</string>
</dict>
</plist>
EOF
# replace HEALTH_SYNC_DIR with actual path, then:
launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

Loading the launch agent immediately enables the persistent service. This step crosses from documentation into activation of a durable background component, which should be treated as a sensitive system modification.

Content

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

EOF # replace HEALTH_SYNC_DIR with actual path, then: launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist ```

Quick start (if you just need it running now, not persistent):

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

Loading the launch agent immediately enables the persistent service. This step crosses from documentation into activation of a durable background component, which should be treated as a sensitive system modification.

Content

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

EOF # replace HEALTH_SYNC_DIR with actual path, then: launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist ```

Quick start (if you just need it running now, not persistent):

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

Using nohup or background start detaches the server from the current session, allowing it to continue running without active oversight. Even though framed as convenience, this creates session persistence and a standing local service that may continue handling sensitive data unexpectedly.

Content

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

Windows

start /B pythonw.exe server.py

macOS / Linux

nohup python3 server.py > server.log 2>&1 &

text

Before starting, kill anything already on port 3001:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The instructions tell the agent to disclose and transmit the API key from a local secret file to the user without warning about handling, storage, or channel security. Secrets echoed into chat or attachments may be retained in logs, copied to insecure devices, or exposed to unintended viewers.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The heartbeat section directs the agent to perform ongoing health-data checks and send derived personal updates, extending behavior from one-time setup/query into persistent surveillance. Because the data is highly sensitive health information, continuous monitoring without narrowly scoped, explicit consent materially increases privacy risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The heartbeat guidance proposes periodic monitoring of sensitive health information and user-facing updates, but it does not require an explicit consent prompt, retention notice, or explanation of monitoring scope. Health data is especially sensitive, so silent or assumed background monitoring creates meaningful privacy and compliance risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This section instructs the agent to continually inspect health data and send derived notifications such as wake-up greetings based on sleep timing. Although not a credential leak, it operationalizes sensitive personal data in an ongoing way that can reveal intimate habits and create unauthorized profiling if enabled without strong consent and limits.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

This later section again recommends launchd persistence that survives reboot. Repetition reinforces a default posture of durable background execution for a health-data receiver, increasing exposure if the user is unaware or no longer using the feature.

Content

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

macOS - launchd (survives reboot):

bash
# create plist at ~/Library/LaunchAgents/com.health-sync.server.plist
# see Agent Instructions section for full plist template
launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

The persisted launch agent path is reiterated as a reboot-surviving mechanism. Persistent components broaden the system's steady-state attack surface and should not be installed casually by an agent.

Content

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

macOS - launchd (survives reboot):

bash
# create plist at ~/Library/LaunchAgents/com.health-sync.server.plist
# see Agent Instructions section for full plist template
launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

Executing launchctl load activates the persistent autorun behavior immediately. That is a sensitive action because it causes long-lived execution beyond the current session and may continue collecting or serving health data indefinitely.

Content

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

bash
# create plist at ~/Library/LaunchAgents/com.health-sync.server.plist
# see Agent Instructions section for full plist template
launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist

Quick (non-persistent):

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

Executing launchctl load activates the persistent autorun behavior immediately. That is a sensitive action because it causes long-lived execution beyond the current session and may continue collecting or serving health data indefinitely.

Content

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

bash
# create plist at ~/Library/LaunchAgents/com.health-sync.server.plist
# see Agent Instructions section for full plist template
launchctl load ~/Library/LaunchAgents/com.health-sync.server.plist

Quick (non-persistent):

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

This quick-start command also launches the server detached from the session, creating a persistent background process handling health data. Detached services increase the risk of unnoticed continued operation and broaden the attack surface on the local host.

Content

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

Windows

start /B pythonw.exe server.py

macOS / Linux

nohup python3 server.py > server.log 2>&1 &

text

## Directory Structure

Static analysis

No suspicious patterns detected.