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<![CDATA[ ## Vulnerability Details **File Location**: `scripts/asl-api.sh:6-24` **Vulnerability Type**: Plaintext transmission of authentication credentials **Risk Level**: High ### Vulnerable Code ```bash ASL_PI_IP="${ASL_PI_IP:-100.116.156.98}" ASL_API_KEY="${ASL_API_KEY:-}" ASL_BASE="http://${ASL_PI_IP}:8073" _asl_call() { local method="$1" local endpoint="$2" local body="$3" if [ -z "$ASL_API_KEY" ]; then echo "ERROR: ASL_API_KEY not set. Source ~/.config/secrets/api-keys.env first." return 1 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 } ``` ### Technical Analysis The shell client constructs its API endpoint with the plaintext `http://` scheme and sends the API key in the `X-API-Key` request header. HTTP provides neither server authentication nor transport encryption. Although the documentation recommends using a Tailscale address, the script does not verify that the destination is reached through Tailscale or another authenticated encrypted tunnel. It also contains a default private-network IP address. If `ASL_PI_IP` is omitted or incorrectly configured, the credential may be sent to an unintended host at that address. An attacker with a suitable network position could observe or modify the HTTP request. A malicious endpoint at the configured address could also directly collect the supplied API key. ### Attack Path 1. The user sets `ASL_API_KEY` and invokes the shell client. 2. The client constructs an endpoint such as `http://100.116.156.98:8073/`. 3. It places the API key in the plaintext `X-API-Key` header. 4. A network-positioned attacker observes the request, or an unintended host receives it. 5. The attacker extracts the key and submits authenticated requests to the reachable ASL Agent API. ...[truncated 691 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require an HTTPS endpoint by default and configure the ASL Agent with a valid TLS certificate. 2. Remove the hard-coded IP fallback. Fail closed when neither `ASL_API_BASE` nor `ASL_PI_IP` is explicitly configured. 3. Reject `http://` endpoints unless the user provides a deliberate insecure-transport override. 4. If plaintext HTTP must be supported over Tailscale, verify and document that the address belongs to the expected tailnet and clearly warn that ordinary LAN or Internet HTTP is unsafe. 5. Keep TLS certificate verification enabled; do not introduce `curl -k` or `--insecure`. 6. Restrict the API key to the minimum backend permissions needed and rotate the key after any suspected exposure. 7. Consider pinning the expected server identity or certificate where operationally practical. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/asl-tool.py:43
Finding
ASL API key transmitted over plaintext HTTP by the Python client<![CDATA[ ## Vulnerability Details **File Location**: `scripts/asl-tool.py:43-64` **Vulnerability Type**: Plaintext transmission of authentication credentials **Risk Level**: High ### Vulnerable Code ```python def _base_url() -> 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
<![CDATA[ ## Remediation Suggestions 1. Make HTTPS mandatory for `ASL_API_BASE` and for the default URL generated from `ASL_PI_IP`. 2. Parse the configured URL and reject unsupported schemes, embedded credentials, malformed hostnames, and unexpected destinations. 3. Permit HTTP only through a conspicuous opt-in intended for loopback or a separately authenticated private tunnel. 4. Preserve the default certificate validation performed by `requests`; do not set `verify=False`. 5. Document secure TLS deployment for the ASL Agent, including certificate lifecycle and hostname verification. 6. Apply least privilege to API keys and provide a rotation process for credentials that may have crossed an untrusted network. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/asl-api.sh:42
Finding
Response-formatting fallback repeats state-changing API requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/asl-api.sh:42-65` **Vulnerability Type**: Duplicate execution of non-idempotent operations **Risk Level**: Medium ### Vulnerable Code ```bash asl_connect() { local node="$1" local monitor="${2:-false}" if [ -z "$node" ]; then echo "Usage: asl_connect <node_number> [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 <node_number>" 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
<![CDATA[ ## Remediation Suggestions 1. Execute each API request exactly once and store its response before attempting to format it. 2. Format the captured response independently; if formatting fails, print the same captured response rather than issuing another request. 3. Use `curl --fail-with-body --show-error` and inspect the HTTP status separately from JSON formatting status. 4. Add idempotency keys for state-changing operations if the backend supports them. 5. Ensure any retry policy is limited to well-defined transient transport failures and uses safe backend deduplication. 6. Return distinct errors for transport failure, HTTP failure, and response-formatting failure. A safer pattern is: ```bash response="$(_asl_call POST /connect "$body")" || return $? if ! printf '%s\n' "$response" | python3 -m json.tool; then printf '%s\n' "$response" fi ``` ]]>
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
Content
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
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Lp3

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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
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.

Description-Behavior Mismatch

Low
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.

Description-Behavior Mismatch

Low
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.

Static analysis

No suspicious patterns detected.