Back to skill

Security audit

Heartbeat Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill openly provides heartbeat and agent-network utilities, but it contains an unsafe uptime script that can execute attacker-controlled code if its log-path environment variable is influenced.

Review this skill before installing. Its ClawSwarm network behavior is mostly disclosed, but enabling it in HEARTBEAT.md may repeatedly contact onlyflies.buzz and fetch untrusted remote messages. Do not run scripts/uptime-log.sh in environments where UPTIME_LOG can be set by untrusted input unless the script is fixed to pass values safely to Python.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/uptime-log.sh:3
Finding

Arbitrary Python Code Execution Through UPTIME_LOG Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/uptime-log.sh, lines 3–24
Vulnerability Type: Environment-variable injection into dynamically constructed Python source
Risk Level: High

Vulnerable Code

bash
LOG="${UPTIME_LOG:-$HOME/.config/heartbeat-pro/uptime.json}"
mkdir -p "$(dirname "$LOG")"

TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
EPOCH=$(date +%s)

if [ ! -f "$LOG" ]; then
  echo '{"heartbeats":[],"total":0}' > "$LOG"
fi

# Append heartbeat (keep last 100)
python3 -c "
import json, sys
with open('$LOG') as f: data = json.load(f)
data['heartbeats'].append({'ts': '$TIMESTAMP', 'epoch': $EPOCH})
data['heartbeats'] = data['heartbeats'][-100:]
data['total'] = data.get('total', 0) + 1
with open('$LOG', 'w') as f: json.dump(data, f)
print(f'💓 Heartbeat #{data[\"total\"]} logged at $TIMESTAMP')
if len(data['heartbeats']) >= 2:
    gap = $EPOCH - data['heartbeats'][-2]['epoch']
    print(f'   Gap since last: {gap//60}m {gap%60}s')
" 2>/dev/null || echo "💓 Heartbeat logged at $TIMESTAMP"

Technical Analysis

The script permits the UPTIME_LOG environment variable to control LOG. It then interpolates that value directly into a double-quoted python3 -c source string:

python
with open('$LOG') as f: data = json.load(f)

Shell quoting of "$LOG" elsewhere in the script protects those operations from ordinary shell word splitting, but it does not make the value safe for insertion into Python source. An attacker-controlled value containing a single quote and additional Python syntax can terminate the intended Python string literal and introduce an expression that executes arbitrary code.

For example, a value conceptually shaped like the following causes a Python function call to be evaluated while constructing the argument to open():

text
' + (__import__('os').system('ATTACKER_COMMAND') or '') + '

Once interpolated, the generated source conta ...[truncated 2100 chars]

Remediation
View remediation

Remediation Suggestions

Do not interpolate filesystem paths or other externally influenced values into dynamically constructed Python source. Pass the log path as a positional argument:

bash
python3 - "$LOG" "$TIMESTAMP" "$EPOCH" <<'PY'
import json
import sys

log_path = sys.argv[1]
timestamp = sys.argv[2]
epoch = int(sys.argv[3])

with open(log_path, encoding="utf-8") as handle:
    data = json.load(handle)

data.setdefault("heartbeats", []).append({
    "ts": timestamp,
    "epoch": epoch,
})
data["heartbeats"] = data["heartbeats"][-100:]
data["total"] = data.get("total", 0) + 1

with open(log_path, "w", encoding="utf-8") as handle:
    json.dump(data, handle)
PY

Additional hardening measures should include:

  1. If custom log locations are unnecessary, remove UPTIME_LOG support and always use the fixed application directory.
  2. If custom paths are required, canonicalize the path and optionally restrict it to an approved directory.
  3. Create the configuration directory with restrictive permissions, such as mkdir -p -m 700.
  4. Create log files with an appropriate restrictive umask, such as umask 077.
  5. Stop suppressing all Python errors. Return a nonzero status and an accurate error message without exposing sensitive data.
  6. Use atomic file replacement and locking to avoid corruption when concurrent heartbeat processes update the same JSON file.
  7. Validate the JSON structure and recover safely from malformed or partially written data.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a general heartbeat and monitoring utility, but the content prominently directs agents to interact with a specific third-party service, fetch tasks and messages, and register with an external hub. This mismatch is dangerous because operators may enable the skill expecting local monitoring while it drives external coordination and data exchange, creating consent, privacy, and supply-chain risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a general heartbeat and monitoring utility, but the content prominently directs agents to interact with a specific third-party service, fetch tasks and messages, and register with an external hub. This mismatch is dangerous because operators may enable the skill expecting local monitoring while it drives external coordination and data exchange, creating consent, privacy, and supply-chain risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a general heartbeat and monitoring utility, but the content prominently directs agents to interact with a specific third-party service, fetch tasks and messages, and register with an external hub. This mismatch is dangerous because operators may enable the skill expecting local monitoring while it drives external coordination and data exchange, creating consent, privacy, and supply-chain risk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/discover-agents.sh (reported line 6)May include surrounding context.

sh
set +u

HUB="https://onlyflies.buzz/clawswarm/api/v1"
CRED_FILE="$HOME/.config/clawswarm/credentials.json"

echo "🔍 Scanning agent network..."

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs the agent to execute shell commands and implies file modification of HEARTBEAT.md, but it does not declare any explicit tool scope or permissions boundaries. This is dangerous because consumers may install or invoke a skill with capabilities broader than expected, increasing the chance of unintended command execution or file changes during heartbeat automation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill uses broad marketing language and heartbeat integration guidance without clear trigger boundaries, making it easy for an agent or operator to invoke it routinely and automatically. In a heartbeat context, ambiguous activation is risky because recurring execution can repeatedly contact external services or run scripts without deliberate review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill encourages agent discovery, bounty checks, message retrieval, and registration with external infrastructure, but it does not prominently warn that data will be transmitted to third parties or that external coordination will occur. This is dangerous because users may unknowingly expose metadata about their agent, environment, interests, or operational cadence through routine heartbeat execution.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill explicitly instructs the agent to fetch channel messages from a third-party service during heartbeat workflows. External transmission is risky in this context because it expands the trust boundary, may reveal operational metadata through repeated polling, and can pull untrusted remote content into an automated agent loop.

Content

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

Agent Network (every 4 hours)

  1. Discover agents: bash path/to/scripts/discover-agents.sh
  2. Check open bounties: curl -s https://onlyflies.buzz/clawswarm/api/v1/tasks?status=open | jq '.tasks[] | {title, bounty_hbar, difficulty}'
  3. Read channel messages: curl -s https://onlyflies.buzz/clawswarm/api/v1/channels/channel_general/messages?limit=5
text

## Agent Network

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script goes beyond the stated heartbeat/service-monitoring purpose and actively interacts with an external agent social/task network by enumerating agents, tasks, and channel messages, and by promoting bounty participation. In an agent-skill context, this expands the trust boundary and can create unreviewed data exposure, behavioral steering, or unauthorized network participation unrelated to the advertised functionality.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/discover-agents.sh (reported line 25)May include surrounding context.

sh
else
  echo ""
  echo "⚠️  Not registered yet. Register to claim bounties:"
  echo "  curl -s -X POST '$HUB/agents/register' \\"
  echo "    -H 'Content-Type: application/json' \\"
  echo "    -d '{\"name\":\"YourName\",\"description\":\"What you do\",\"capabilities\":[\"your\",\"skills\"]}'"
  echo ""

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script reads local credential metadata from a user configuration file to support registration and bounty workflows that are unrelated to heartbeat monitoring. Even though it only extracts an agent_id here, accessing credential-associated local state in a broader-than-advertised feature set increases privacy risk and normalizes unnecessary credential handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs a network request by default to a hard-coded third-party domain, which can disclose agent execution, IP address, timing, and environment metadata without explicit user intent. Because this occurs in a generic health-check skill, the behavior is more specific than advertised and creates an unnecessary outbound communication channel that could be used for tracking or dependency on an external operator-controlled endpoint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.