Back to skill

Security audit

Allstar Link node control ASL3 (ASL3 Node Control)

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real AllStar Link control client, but it needs Review because it can change live radio-node connections and sends the API key over HTTP.

Install only if you control the ASL Agent backend and are comfortable letting the agent issue live connect/disconnect commands. Use HTTPS or a trusted encrypted tunnel, avoid ordinary LAN/Internet HTTP, keep the API key least-privileged, and require explicit confirmation before connect, disconnect, net start, net stop, or cron-driven net tick actions.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/asl-api.sh:6
Finding

ASL API key transmitted over plaintext HTTP by the shell client

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/asl-tool.py:43
Finding

ASL API key transmitted over plaintext HTTP by the Python client

Content
View full analysis
str: base = _env("ASL_API_BASE") if base: return base.rstrip("/") + "/" ip = _env("ASL_PI_IP") if not ip: raise SystemExit("Missing ASL_API_BASE or ASL_PI_IP in environment") return f"http://{ip}:8073/" def _api_key() -> str: key = _env("ASL_API_KEY") if not key: raise SystemExit("Missing ASL_API_KEY in environment") return key def _req(method: str, path: str, *, json_body: dict | None = None) -> dict: url = urljoin(_base_url(), path.lstrip("/")) headers = {"X-API-Key": _api_key()} r = requests.request(method, url, headers=headers, json=json_body, timeout=30) ``` ### Technical Analysis When `ASL_API_BASE` is absent, the Python client unconditionally constructs a plaintext HTTP URL from `ASL_PI_IP`. It then transmits the API key in the `X-API-Key` header. The optional `ASL_API_BASE` setting is also accepted without validating its scheme or destination, so a user can inadvertently configure another plaintext endpoint. The `requests` library cannot provide TLS confidentiality or endpoint authentication when the URL uses HTTP. Use of a Tailscale address may supply protection at the overlay-network layer, but this protection is environmental rather than enforced by the client. The client can be used on an ordinary LAN or with an arbitrary HTTP destination. ### Attack Path 1. The user exports `ASL_PI_IP` or an HTTP-valued `ASL_API_BASE`, together with `ASL_API_KEY`. 2. The client constructs the request URL without requiring HTTPS. 3. `_req` includes the key in the `X-API-Key` header. 4. An attacker able to observe the relevant network path captures the request, or a mistakenly configured endpoint records the credential. 5. The attacker reuses the key against a ...[truncated 554 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/asl-api.sh:42
Finding

Response-formatting fallback repeats state-changing API requests

Content
View full analysis
[monitor]" return 1 fi echo "Connecting to node $node..." _asl_call POST /connect "{\"node\": \"$node\", \"monitor_only\": $monitor}" | python3 -m json.tool 2>/dev/null || _asl_call POST /connect "{\"node\": \"$node\", \"monitor_only\": $monitor}" } asl_disconnect() { local node="$1" if [ -z "$node" ]; then echo "Usage: asl_disconnect " return 1 fi echo "Disconnecting from node $node..." _asl_call POST /disconnect "{\"node\": \"$node\"}" | python3 -m json.tool 2>/dev/null || _asl_call POST /disconnect "{\"node\": \"$node\"}" } asl_disconnect_all() { echo "Disconnecting all nodes..." _asl_call POST /disconnect-all | python3 -m json.tool 2>/dev/null || _asl_call POST /disconnect-all } ``` ### Technical Analysis Each state-changing API request is piped into a JSON formatter. The shell `||` fallback repeats `_asl_call` if the pipeline reports failure. A formatting failure does not prove that the original API operation failed. The backend may successfully process the first POST and then return malformed, truncated, empty, or otherwise non-JSON output. In that case, `python3 -m json.tool` exits unsuccessfully and the fallback submits an identical second POST. This incorrectly couples presentation-layer failure to operation retry. The duplicate is especially problematic because no idempotency key or backend deduplication mechanism is present in the reviewed client. The pipeline is not a `curl | bash` remote-execution construct. API responses are sent only to local JSON formatters. Consequently, the pre-scan warning for remote payload retriev ...[truncated 1189 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/asl-api.sh (reported line 21)May include surrounding context.

sh
fi

    if [ -n "$body" ]; then
        curl -s -X "$method" -H "X-API-Key: $ASL_API_KEY" -H "Content-Type: application/json" -d "$body" "${ASL_BASE}${endpoint}"
    else
        curl -s -X "$method" -H "X-API-Key: $ASL_API_KEY" "${ASL_BASE}${endpoint}"
    fi

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents use of environment variables, filesystem state, network access, and shell execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an overbroad execution surface where an agent may invoke capabilities beyond what a reviewer or runtime policy expects, increasing the chance of unintended secret exposure or remote state changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill is explicitly designed to control remote amateur radio nodes through a REST API, including connect, disconnect, and timed session actions, but it does not present a clear warning that these commands alter live system state. In an agent setting, this can lead to unsafe or unintended operational changes if a user asks for status-like assistance and the agent performs control actions without adequate confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script hardcodes the API base URL to use plain HTTP and sends the X-API-Key header over that channel, so anyone on the local network path or able to intercept traffic can read or modify authenticated control requests. Because this skill performs node control actions such as connect, disconnect, and audit access, lack of transport security enables credential theft and command tampering, not just passive observation.

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/asl-api.sh (reported line 21)May include surrounding context.

sh
fi

    if [ -n "$body" ]; then
        curl -s -X "$method" -H "X-API-Key: $ASL_API_KEY" -H "Content-Type: application/json" -d "$body" "${ASL_BASE}${endpoint}"
    else
        curl -s -X "$method" -H "X-API-Key: $ASL_API_KEY" "${ASL_BASE}${endpoint}"
    fi

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The documentation tells users to source a secrets file containing API credentials into the shell environment without any warning about credential handling risks. In agent-assisted or shared-shell contexts, this may expose bearer tokens to subprocesses, logs, history, or broader session state, making accidental secret leakage more likely.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest describes a REST-based monitor/control skill for AllStar Link nodes. In addition to that core function, the code creates and writes per-user local state files for favorites under ~/.openclaw/state/asl-control, which is an extra persistence capability not implied by the description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest frames the skill as monitoring and controlling amateur radio nodes via REST API. This file also implements persistent net profiles, timed sessions, and cron-friendly auto-disconnect enforcement using local files and timers, which is broader workflow automation than the description suggests.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.