Back to skill

Security audit

UniFi Network

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent UniFi monitoring tool, but it needs review because it handles gateway credentials insecurely and silently saves sensitive network data.

Install only if you are comfortable giving the skill access to sensitive UniFi network data. Use a dedicated read-only local account, restrict the credential file permissions, avoid sharing raw output, and be aware that the current scripts disable TLS verification and write a local debug dump containing network inventory.

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/unifi-api.sh:40
Finding
TLS Certificate Verification Is Disabled for Authentication and API Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/unifi-api.sh:40-44`, `scripts/unifi-api.sh:77` **Vulnerability Type**: Insecure TLS configuration **Risk Level**: High ### Vulnerable Code ```bash curl -sk -c "$cookie_file" \ -H "Content-Type: application/json" \ -X POST \ "$UNIFI_URL/api/auth/login" \ --data "$payload" >/dev/null ``` ```bash curl -sk -b "$UNIFI_COOKIE_FILE" "$full_url" ``` ### Technical Analysis The `-k` option instructs curl to accept an HTTPS server without validating its certificate. It is used for both the login request and every authenticated API request. Although traffic remains encrypted, the client does not verify that it is communicating with the intended UniFi gateway. An attacker with a suitable local network interception position can present an arbitrary certificate and impersonate the gateway. The login request transmits the configured username and password in its JSON body, while subsequent requests transmit the authenticated session cookie. The behavior is documented in `README.md:94-96`, but documentation does not mitigate the underlying loss of server authentication. ### Attack Path 1. The attacker gains a position capable of influencing local traffic, such as control over Wi-Fi, DNS, ARP resolution, routing, or another device on the local network. 2. The attacker redirects traffic intended for the configured UniFi host to a malicious HTTPS server. 3. The malicious server presents an untrusted or attacker-generated certificate. 4. Because curl is invoked with `-k`, the client accepts the certificate without warning. 5. During `/api/auth/login`, the attacker receives the configured username and password. 6. The attacker can attempt to authenticate to the real gateway using the captured credentials or return falsified API responses to the monitoring scripts. 7. Authenticated session cookies may also be captured from subsequent requests. ### Impact Assessment Successful exploitation can disclose t ...[truncated 449 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `-k` from login and API requests so certificate verification is enabled by default. 2. Support a user-configured trusted CA bundle: ```bash curl --fail-with-body --silent --show-error \ --cacert "$UNIFI_CA_FILE" \ -c "$cookie_file" \ -H "Content-Type: application/json" \ -X POST \ "$UNIFI_URL/api/auth/login" \ --data "$payload" ``` 3. Alternatively, support certificate or public-key pinning with curl’s `--pinnedpubkey` option. 4. Provide instructions for exporting and trusting the gateway certificate or the local CA that issued it. 5. If insecure TLS must remain available for legacy deployments, require an explicit setting such as `UNIFI_INSECURE_TLS=true`, keep secure verification as the default, and print a prominent warning. 6. Use `--fail-with-body --silent --show-error` and verify both HTTP status and expected API response fields. 7. Require a dedicated read-only UniFi account so credential compromise cannot grant administrative configuration privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dashboard.sh:39
Finding
Dashboard Unconditionally Persists Sensitive Network Inventory in an Undisclosed Debug File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dashboard.sh:39-48` **Vulnerability Type**: Unnecessary persistent storage of sensitive network data **Risk Level**: Medium ### Vulnerable Code ```bash # Debug: Dump all JSON to a file for troubleshooting jq -n \ --argjson health "$HEALTH" \ --argjson devices "$DEVICES" \ --argjson clients "$CLIENTS" \ --argjson portforward "$PORTFWD" \ --argjson networks "$NETWORKS" \ --argjson wlans "$WLANS" \ '{health: $health, devices: $devices, clients: $clients, networks: $networks, wlans: $wlans}' \ > dashboard_debug_dump.json 2>/dev/null ``` ### Technical Analysis Every execution of `dashboard.sh` creates or overwrites `dashboard_debug_dump.json` in the process’s current working directory. This occurs even when the user only requests terminal output and has not enabled debugging. The file contains raw API responses for network health, devices, active clients, network configuration, and WLAN configuration. Depending on the UniFi response schema, this can include internal hostnames, IP addresses, MAC addresses, SSIDs, subnets, VLAN information, gateway identifiers, and additional fields omitted from the human-readable dashboard. The file is not automatically deleted, its creation is not disclosed in the usage documentation, and its permissions depend on the caller’s umask. It may therefore remain accessible in shared directories, workspace artifacts, backups, or source-control repositories. This write exceeds the minimum privileges and storage behavior necessary to generate a monitoring dashboard. ### Attack Path 1. A user or Agent runs `bash scripts/dashboard.sh` from a project, shared, synchronized, or artifact-collected directory. 2. The script silently writes raw network information to `dashboard_debug_dump.json`. 3. The file remains after the dashboard process exits. 4. Another local user, automated backup process, source-control operation, CI artifact collector, ...[truncated 652 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the unconditional debug dump entirely. 2. If troubleshooting output is required, require an explicit opt-in flag or environment variable, such as `UNIFI_DEBUG_DUMP=true`. 3. Create debug files securely with `mktemp` under a private directory and enforce mode `0600`. 4. Redact or whitelist fields instead of storing complete raw API responses. 5. Delete temporary debug files through an `EXIT` trap unless the user explicitly requests retention. 6. If retained output is requested, require an explicit destination, reject unsafe destinations where appropriate, and clearly disclose the sensitivity and lifetime of the file. 7. Add `dashboard_debug_dump.json` to `.gitignore` as defense in depth, although this must not replace removal of the automatic write. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:26
Finding
Credential Setup Stores a Reusable Gateway Password Without Enforcing Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `README.md:26-36` **Additional Location**: `SKILL.md:30-39`; credential loading occurs at `scripts/unifi-api.sh:6-24` **Vulnerability Type**: Insecure plaintext credential-file permissions and insufficient least-privilege guidance **Risk Level**: Medium ### Vulnerable Code ```bash mkdir -p ~/.openclaw/credentials cat > ~/.openclaw/credentials/unifi.json << 'EOF' { "host": "your-gateway-ip", "username": "your_username", "password": "your_password", "note": "Local Read-Only account on UniFi OS" } EOF ``` The runtime then reads the reusable password directly from the file: ```bash CONFIG_FILE="${UNIFI_CONFIG_FILE:-$HOME/.openclaw/credentials/unifi.json}" UNIFI_USER=$(jq -r '.username' "$CONFIG_FILE") UNIFI_PASS=$(jq -r '.password' "$CONFIG_FILE") UNIFI_SITE=$(jq -r '.site // "default"' "$CONFIG_FILE") ``` ### Technical Analysis Authenticated access is necessary for the declared UniFi monitoring functionality, so reading a credential from a user-configured location is not inherently excessive. However, the documented setup creates the directory and plaintext JSON file without enforcing private permissions. The resulting mode depends on the user’s current umask. On systems with permissive defaults or shared group access, the credential file may be readable by unintended local users. The runtime does not verify file ownership or reject group/world-readable permissions. The README also instructs users to create a “local admin.” Although the JSON example contains a note saying “Local Read-Only account,” the setup instructions do not explicitly require that the account’s actual UniFi permissions be restricted to read-only Network access. A note inside the local JSON file does not enforce authorization. ### Attack Path 1. A user follows the documented setup on a shared system or under a permissive umask. 2. `~/.openclaw/credentials` or `unifi.json` receives group-readable or world-readable permis ...[truncated 887 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Update setup instructions to create the directory and file with restrictive permissions: ```bash install -d -m 700 "$HOME/.openclaw/credentials" umask 077 cat > "$HOME/.openclaw/credentials/unifi.json" <<'EOF' { "host": "your-gateway-ip", "username": "your_readonly_username", "password": "your_password", "site": "default" } EOF chmod 600 "$HOME/.openclaw/credentials/unifi.json" ``` 2. Explicitly require a dedicated local account with only the minimum read-only permissions needed for the Network application. 3. Do not describe the account merely as a “local admin”; document the exact least-privilege role configuration. 4. At runtime, verify that the credential file is owned by the current user and is not group- or world-readable. Refuse to proceed or display a clear warning if permissions are unsafe. 5. Consider supporting a platform credential store or secret manager instead of a plaintext JSON password. 6. Avoid exporting the password or including it in logs, errors, debug files, or process command-line arguments. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

### 1. Create a Local Admin Account

1. Open your UniFi OS console (e.g., `https://your-gateway-ip`)
2. Go to **OS Settings → Admins & Users**
Confidence
60% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README instructs users to store UniFi credentials, including a local admin password, in a plaintext file under the user's home directory without any warning about file permissions, secret handling, or alternative secure storage. If the host is multi-user, compromised, backed up insecurely, or logs/home directories are exposed, these credentials could be recovered and used to access the UniFi controller.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
→ Wrong username/password. Must be a **local** admin, not Ubiquiti cloud account.

**SSL certificate error**  
→ UniFi uses self-signed certs. The scripts use `-k` to skip verification.

**Empty data or "Invalid site"**  
→ Most setups use `default`. Check your site name in the UniFi Network URL.
Confidence
98% confidence
Finding
The README explicitly states that the scripts use curl -k to skip TLS certificate verification for a login flow carrying administrator credentials. Disabling certificate validation enables man-in-the-middle interception or spoofing of the UniFi gateway, which can expose credentials and allow falsified monitoring data.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill clearly expects shell and network access (`bash` scripts calling a local HTTPS API) but does not declare an explicit tool scope. That weakens least-privilege controls and makes it easier for a runtime to grant broader capabilities than users or reviewers expect.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill advertises collection of device, client, traffic, and alert data but does not prominently warn that outputs may contain sensitive network inventory, hostnames, IPs, MAC addresses, and usage patterns. This can lead to unintentional disclosure of private infrastructure details to users, logs, or downstream systems.

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

Create the credentials file: `~/.openclaw/credentials/unifi.json`

```json
{
Confidence
90% confidence
Finding
The setup instructs users to store a UniFi username and password in a persistent plaintext credentials file under the home directory. Persistent local secrets increase the risk of credential theft from other local processes, backups, logs, or accidental file disclosure, especially because these credentials grant access to network-management data.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The document enumerates authenticated UniFi endpoints that expose sensitive administrative and operational data, including site health, admins, devices, and clients, but does not prominently warn that these responses may contain private network topology, user/device identifiers, and privileged account information. In a skill designed to query a local gateway API, this omission increases the risk that the agent will over-collect or disclose sensitive data to users without adequate minimization or consent boundaries.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Several listed endpoints expose detailed monitoring and DPI-style visibility, such as active clients, events, alarms, and per-client traffic/application statistics, yet the document does not clearly warn that this can reveal user activity patterns and device usage. In the context of a monitoring skill, that makes privacy leakage more likely because the capability is directly aligned with inspecting who is on the network and what they are doing.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Although the section emphasizes GET-only access, the listed configuration endpoints still disclose highly sensitive security and infrastructure details such as firewall rules, WLAN settings, RADIUS profiles/accounts, DynamicDNS, and port forwards. Exposure of this information can materially aid an attacker by revealing network architecture, authentication integrations, externally reachable services, and defensive controls even without any write capability.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
Allowing full dashboard output to be written to an arbitrary path via an environment variable enables uncontrolled persistence of sensitive network data and can redirect output into unintended locations. In shared or automated environments, this makes accidental disclosure easier and may allow overwriting files accessible to the executing user.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The script retrieves and displays detailed configuration data including port forwards, firewall rules, networks, WLANs, routing, and system information, which goes beyond a narrow 'status/monitoring' scope and materially increases exposure of sensitive network internals. In an agent skill context, this broad collection can leak topology, segmentation, remote access exposure, and security policy details to downstream consumers or logs even when the user only asked for health or client status.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The script always writes a local debug JSON dump containing health, device, client, network, and WLAN data to disk, creating a persistent copy of sensitive information without user awareness. This increases the risk of local disclosure through other users, backups, artifact collection, or later compromise of the host running the skill.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The debug dump persists potentially sensitive client and network data to disk without any user-facing warning, confirmation, or opt-in, violating least surprise and safe handling expectations for a monitoring skill. Because the skill context is read-only monitoring, hidden data persistence is more dangerous: users may reasonably expect transient display, not silent local retention of inventory and client information.

External Transmission

Medium
Category
Data Exfiltration
Content
payload=$(jq -nc --arg username "$UNIFI_USER" --arg password "$UNIFI_PASS" '{username:$username,password:$password}')
  
  # Try login
  curl -sk -c "$cookie_file" \
    -H "Content-Type: application/json" \
    -X POST \
    "$UNIFI_URL/api/auth/login" \
Confidence
98% confidence
Finding
This external transmission sends authentication credentials to the UniFi login endpoint while TLS verification is disabled, making the transmission susceptible to interception or redirection. In the context of a network-monitoring skill, compromise of these credentials could expose the entire UniFi environment, including device inventory, clients, and administrative operations.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The script uses curl with -k, disabling TLS certificate verification during authentication to the UniFi controller. This allows a man-in-the-middle on the network to impersonate the controller, capture credentials, and issue malicious responses or session cookies, which is especially risky for a network-management skill that handles administrative access.

Missing User Warnings

Low
Confidence
86% confidence
Finding
The script performs an API request to retrieve UniFi alarm data, which may transmit system/site context over the network, but the file contains no confirmation, user-facing log message, or explanatory comment beyond a brief header. For a code file, this qualifies as a missing warning because the network access is not disclosed to the user within the script itself.

Missing User Warnings

Low
Confidence
86% confidence
Finding
The script loads username and password values from the configured JSON file and uses them for authentication, which is access to sensitive credentials. While the code comments describe functionality, there is no user-facing warning, prompt, or explicit disclosure in this file about handling stored credentials.

Missing User Warnings

Low
Confidence
78% confidence
Finding
The helper issues authenticated GET requests to the UniFi controller and returns the response directly, which can expose system or user-related data depending on the endpoint requested. The script contains implementation comments, but no user-facing disclosure that it will contact the controller and retrieve data on the user's behalf.

Static analysis

No suspicious patterns detected.