T09 · Insecure Skill Coding Practices
- Location
scripts/clawpulse-monitor.py:165- Finding
Unauthenticated Internal Status Endpoint Exposes Operational Metadata
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is coherent as a ClawPulse status bridge, but it exposes a network status service and credentials more broadly than its protections and warnings justify.
Review before installing. Only run it on a machine and network where exposing assistant status is acceptable, prefer 127.0.0.1 or a tightly controlled Tailscale interface, treat printed tokens and QR codes as secrets, and stop/remove the background processes when no longer needed.
scripts/clawpulse-monitor.py:165Unauthenticated Internal Status Endpoint Exposes Operational Metadata
scripts/clawpulse-monitor.py:11Bridge Bearer Token Can Be Sent to an Arbitrary or Cleartext Destination
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
req = urllib.request.Request(BRIDGE_URL)
if BRIDGE_TOKEN:
req.add_header("Authorization", f"Bearer {BRIDGE_TOKEN}")
with urllib.request.urlopen(req, timeout=TIMEOUT_SEC) as r:
raw = r.read()
obj = json.loads(raw.decode("utf-8"))
return obj
The /internal endpoint returns the full monitor state without checking APP_TOKEN, even though /health and /status are token-protected. Because the state includes thought text, token usage, timestamps, assistant identity, and internal health data, anyone who can reach the service can query sensitive operational information, which is especially risky given the broad default bind setting.
The script claims a safer dry-run/default posture, but actually defaults to BIND_HOST=0.0.0.0 and prints setup secrets to stdout, including the bearer token and setup link/QR contents. In a setup/integration skill, this is dangerous because it can unintentionally expose a remotely reachable status service and leak credentials via terminal history, screenshots, logs, or shared sessions.
The skill describes shell, network, environment, and file operations but does not declare any explicit tool scope or permissions boundary. In an agent setting, this weakens least-privilege controls and can let the skill invoke broader capabilities than a user may reasonably expect, increasing the chance of unsafe file, network, or command execution during setup and troubleshooting.
The skill explicitly recommends a remote-ready bind to 0.0.0.0 and states that setup prints bearer tokens and QR codes, but it does not foreground the risks of exposing an HTTP service and sensitive credentials on LAN/Tailscale. If the endpoint is reachable by unintended peers or the token/QR is observed in logs, terminal history, screenshots, or shared sessions, an attacker could query the status bridge or reuse the credential.
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.
Then configure app with monitor endpoint/token (from script output or QR), not bridge token.
## Troubleshooting
- HTTP blocked on iOS: ensure app Info.plist has ATS exception for development, or use HTTPS.
- 401 auth error: token mismatch; regenerate and reapply.
- 403 forbidden: source IP is not local/Tailscale; confirm the device is connected to Tailscale.
- Timeout: check bridge process and network reachability.
The server binds to 0.0.0.0 by default, exposing the monitoring API on all network interfaces unless the operator overrides it. In the context of a status bridge that carries internal operational metadata and also contains an unauthenticated /internal endpoint, this expands the reachable attack surface and increases the chance of unauthorized access.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
PY
)
printf 'STATUS_TOKEN=%s\n' "$TOKEN" > "$ENV_FILE"
chmod 600 "$ENV_FILE"
else
source "$ENV_FILE"
TOKEN="${STATUS_TOKEN:-}"
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
PY
)
printf 'STATUS_TOKEN=%s\n' "$TOKEN" > "$ENV_FILE"
chmod 600 "$ENV_FILE"
else
source "$ENV_FILE"
TOKEN="${STATUS_TOKEN:-}"
The generated Python service returns fixed Chinese strings such as "连接异常", "工作中", and Chinese thought messages in its API payload. This imposes a specific language on all consumers without any opt-in, configuration, or justification for a locale-specific deployment.
The setup link is generated from $STATUS_TOKEN, but the shell script stores the token in TOKEN unless the env file is sourced later, so the displayed QR/setup URL can contain an empty or incorrect token. This can lead users to deploy a broken configuration, disable safeguards while troubleshooting, or assume authentication is working when it is not.
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.
source "$ENV_FILE"
export BIND_HOST PORT WORKSPACE
set +a
nohup python3 "$BRIDGE_PY" >"$LOG_FILE" 2>&1 &
sleep 1
echo "ClawPulse bridge running"
The runtime note states local-only mode is the safer default, but the script default is remote binding on 0.0.0.0, which creates a misleading trust boundary for operators. This kind of documentation/behavior mismatch is security-relevant because users may assume the service is local-only and expose a token-protected endpoint on the network without realizing it.
The script binds the monitor to 0.0.0.0 by default, exposing the token-protected health endpoint on all network interfaces rather than restricting it to localhost or a Tailscale-specific address. In the context of a status bridge carrying authentication tokens and machine status metadata, this materially increases the attack surface and can allow unintended remote access if host firewalling is weak or absent.
The script overwrites the environment file containing STATUS_TOKEN and MONITOR_TOKEN without an explicit confirmation step, which can silently rotate or replace credentials. In an integration setup flow, that can break existing clients, invalidate expected trust relationships, or cause accidental credential loss during routine use.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
exit 1
fi
cp "$MONITOR_SRC" "$MONITOR_PY"
chmod 700 "$MONITOR_PY"
TS_DNS=""
TS_IP=""
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
exit 1
fi
cp "$MONITOR_SRC" "$MONITOR_PY"
chmod 700 "$MONITOR_PY"
TS_DNS=""
TS_IP=""
The script intentionally establishes a persistent background service using nohup, causing the monitor to continue running after the setup command exits. In this skill's context, persistence matters because the monitor serves a network endpoint and handles bridge credentials, so an operator may unintentionally leave a long-lived exposed service active.
source "$ENV_FILE"
export WORKSPACE MONITOR_BIND_HOST MONITOR_PORT BRIDGE_URL BRIDGE_TOKEN="$STATUS_TOKEN"
set +a
nohup python3 "$MONITOR_PY" >"$LOG_FILE" 2>&1 &
sleep 1
echo "ClawPulse monitor running"
This Python file contains user-facing natural-language strings such as "连接异常", "监控器启动中。", and other Chinese status messages. The file does not offer a language choice or document that the monitor is intentionally region-specific, which conflicts with the policy against forcing a specific language without user opt-in.
The monitor emits user-visible work-state values and recovery messages only in Chinese, including "工作中", "闲置", and "监控器判定离线,等待恢复。". Because no opt-in or locale selection is present, these strings indicate a language policy violation in natural-language output.
Starting a long-running background process is a safety-relevant operation for code files, and this script does not provide a warning or confirmation immediately before executing nohup python3. Although the dry-run mentions starting/restarting the monitor, the apply path lacks a direct disclosure right before process launch.
No suspicious patterns detected.