Back to skill

Security audit

Closeli Open Device Live Query

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated device-live purpose, but it handles a sensitive API key from a shared persistent file and can send it to a configurable gateway with TLS verification disabled.

Review before installing. Use a least-privilege API key, keep AI_GATEWAY_VERIFY_SSL enabled, verify AI_GATEWAY_HOST is the intended trusted Closeli gateway, and ensure ~/.openclaw/.env is readable only by the intended OpenClaw service user. Avoid using this skill in environments where unrelated skills can modify the shared configuration file.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
get_live_url.py:77
Finding
Bearer Credential Exfiltration Through Unrestricted Gateway Configuration and Optional TLS Bypass<![CDATA[ ## Vulnerability Details **File Location**: `get_live_url.py`, lines 77-99 **Vulnerability Type**: Unrestricted credential destination and optional TLS certificate verification bypass **Risk Level**: High ### Vulnerable Code ```python def get_api_host(env_vars): """ 获取网关地址:~/.openclaw/.env 中的 AI_GATEWAY_HOST,未配置则用默认值。 """ host = env_vars.get("AI_GATEWAY_HOST") return host.rstrip("/") if host else DEFAULT_API_HOST def get_verify_ssl(env_vars): """ 判断是否启用 TLS 证书验证。默认启用。 仅当 ~/.openclaw/.env 中显式设置 AI_GATEWAY_VERIFY_SSL=false 时禁用(仅开发环境)。 """ val = env_vars.get("AI_GATEWAY_VERIFY_SSL", "true").lower() return val not in ("false", "0", "no") def api_post(api_key, api_host, verify_ssl, path, body=None): """通用 POST 请求""" url = f"{api_host}{path}" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", } data = json.dumps(body).encode("utf-8") if body else b"" try: with httpx.Client(verify=verify_ssl, timeout=120.0, headers=headers) as client: resp = client.post(url, content=data) ``` ### Technical Analysis The persistent `AI_GATEWAY_HOST` setting is accepted without validating its scheme or destination against an allowlist. The script subsequently attaches the API key as a bearer credential to requests made to that configured destination. The same shared configuration file can set `AI_GATEWAY_VERIFY_SSL=false`, causing `httpx` to disable certificate verification. Consequently, the script does not enforce the documented trusted gateway as the credential recipient and does not guarantee an authenticated TLS channel. Although customization may be useful in development, allowing persistent shared configuration to control both the credential destination and TLS verification exceeds the minimum privileges required to query the declared Closeli API. The legitimate production operation only requires HTTPS communication with a k ...[truncated 1475 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce an explicit allowlist of trusted gateway hostnames, with `ai-open.icloseli.com` as the production destination. 2. Require the `https` scheme and reject URLs containing user information, fragments, unexpected ports, or untrusted hostnames. 3. Remove persistent support for `AI_GATEWAY_VERIFY_SSL=false`. 4. If development endpoints are necessary, require an explicit per-invocation development flag and prevent production API keys from being sent while verification is disabled. 5. Use a dedicated development credential with minimal privileges for non-production gateways. 6. Fail closed when gateway or TLS settings are malformed instead of silently accepting them. 7. Consider certificate pinning where operationally feasible. 8. Restrict `~/.openclaw/.env` to the service user with mode `0600` and prevent unrelated Skills from modifying it. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
get_live_url.py:37
Finding
Overbroad Parsing of a Shared Multi-Skill Credential File<![CDATA[ ## Vulnerability Details **File Location**: `get_live_url.py`, lines 37-58 **Vulnerability Type**: Excessive access to unrelated shared credentials **Risk Level**: Low ### Vulnerable Code ```python def load_env_file(): """ 从 ~/.openclaw/.env 文件加载配置。 这是 OpenClaw 客户端写入的持久化真值源,由所有 skill 共享。 """ env_path = Path.home() / ".openclaw" / ".env" if not env_path.exists(): return {} result = {} try: with open(env_path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" in line: key, _, value = line.partition("=") key = key.strip() value = value.strip().strip('"').strip("'") result[key] = value except Exception as e: # 读盘失败时按"未配置"继续,不阻断后续 CLI 参数兜底 print(f"⚠️ 读取配置文件 {env_path} 失败,将按未配置处理: {e}", file=sys.stderr) return result ``` ### Technical Analysis The Skill needs only three settings: - `AI_GATEWAY_API_KEY` - `AI_GATEWAY_HOST` - `AI_GATEWAY_VERIFY_SSL` However, `load_env_file()` parses every key and value in the shared `~/.openclaw/.env` file and stores them in the `result` dictionary. The documentation explicitly states that this file is shared by all Skills, so it may contain credentials unrelated to the declared device-live functionality. No current code path was found that transmits or prints these unrelated values. Nevertheless, loading all of them into process memory violates data minimization and least-privilege principles. It unnecessarily makes unrelated secrets available to debugging facilities, exception inspection, memory dumps, or future code changes. ### Attack Path 1. The shared `~/.openclaw/.env` contains the gateway settings required by this Skill and additional secrets used by other Skills. 2. The user or agent invokes `get_live_url.py`. 3. ` ...[truncated 1058 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse only the three explicitly required keys and discard all other entries immediately. 2. Prefer a Skill-specific configuration or credential file rather than a shared multi-Skill secret file. 3. Where supported, retrieve `AI_GATEWAY_API_KEY` through a scoped operating-system credential store or OpenClaw secret provider. 4. Ensure sensitive configuration dictionaries are never included in logs, exception messages, diagnostics, or serialized output. 5. Restrict the credential file to mode `0600` and the dedicated service account. 6. Separate credentials by service and privilege so compromise of one Skill does not expose credentials belonging to others. A minimal filtering approach would retain a fixed allowlist: ```python allowed_keys = { "AI_GATEWAY_API_KEY", "AI_GATEWAY_HOST", "AI_GATEWAY_VERIFY_SSL", } if key in allowed_keys: result[key] = value ``` ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
openclaw:
    requires:
      bins: ["python3"]
      configPaths: ["~/.openclaw/.env"]
    primaryEnv: "AI_GATEWAY_API_KEY"
---
Confidence
97% confidence
Finding
The skill depends on a shared persistent credential file `~/.openclaw/.env` containing `AI_GATEWAY_API_KEY`, and the document explicitly notes that all skills under the same user can read it. That creates a cross-skill credential exposure path where any compromised or overly broad skill can steal the API key and access device-related APIs.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
`POST /api/device/live` is used to obtain the H5 player live link for a specified device. The API verifies device ownership and then returns a player URL that can be opened directly in a browser.

## ⚠️ Display Rules (MUST be strictly followed)

The script outputs structured data in JSON format, which is the expected behavior. The display rules below are formatting instructions for the agent: the agent MUST parse the JSON output from the script, convert it into a user-friendly format according to the following rules before displaying it, and MUST NOT display the raw JSON directly.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## ⚠️ Display Rules (MUST be strictly followed)

The script outputs structured data in JSON format, which is the expected behavior. The display rules below are formatting instructions for the agent: the agent MUST parse the JSON output from the script, convert it into a user-friendly format according to the following rules before displaying it, and MUST NOT display the raw JSON directly.

The script output includes the `_device_name` field (device name), which is used for display.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
获取指定设备的 H5 播放器直播链接。自动调用 device/list 获取设备名称。

配置来源(统一规则):
  - 持久化:~/.openclaw/.env (OpenClaw 客户端的"设置 API Key"会自动写入此文件)
  - 临时覆盖:仅 API_KEY 支持命令行 --api-key,覆盖 .env 中的同名配置
  - 不再读取任何 AI_GATEWAY_* 环境变量
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
从 ~/.openclaw/.env 文件加载配置。
    这是 OpenClaw 客户端写入的持久化真值源,由所有 skill 共享。
    """
    env_path = Path.home() / ".openclaw" / ".env"
    if not env_path.exists():
        return {}
    result = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
从 ~/.openclaw/.env 文件加载配置。
    这是 OpenClaw 客户端写入的持久化真值源,由所有 skill 共享。
    """
    env_path = Path.home() / ".openclaw" / ".env"
    if not env_path.exists():
        return {}
    result = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares network and file-read capabilities implicitly but does not define an explicit tool/permission scope. In an agent environment, missing scope boundaries can let the runtime grant broader access than intended, increasing the blast radius if the skill is misused or the implementation changes.

Session Persistence

Medium
Category
Rogue Agent
Content
### Configuration Source

The script reads `~/.openclaw/.env` as the single persistent configuration source. This file is shared by all skills and uses the format `KEY=VALUE` (one entry per line). OpenClaw clients write to this file when the user updates settings. The script does NOT read any `AI_GATEWAY_*` environment variables — env variables are intentionally ignored to avoid stale Gateway-process snapshots overriding the user's latest config.

## Security Notes
Confidence
92% confidence
Finding
The skill intentionally uses a single persistent shared `.env` file as the authoritative configuration source and ignores process environment overrides. This creates session persistence for credentials and host settings across runs and across skills, so stale, poisoned, or maliciously modified values can silently affect future executions.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
## Security Notes

- The shared credential file `~/.openclaw/.env` is readable by all skills under the same user. Ensure file permissions are restricted (e.g. `chmod 600 ~/.openclaw/.env`) and that only the OpenClaw service user has access. The IM clients write to this file under that user's home directory.
- TLS certificate verification is enabled by default. You MUST NOT disable it in production environments (disabling it introduces man-in-the-middle attack risks, and attackers may intercept API_KEY and device data)
- Before use, you MUST confirm that AI_GATEWAY_HOST points to a trusted domain
- You MUST use a least-privilege API_KEY to avoid reusing high-privilege credentials. This skill only requires permission to retrieve device live links
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
def get_verify_ssl(env_vars):
    """
    判断是否启用 TLS 证书验证。默认启用。
    仅当 ~/.openclaw/.env 中显式设置 AI_GATEWAY_VERIFY_SSL=false 时禁用(仅开发环境)。
    """
    val = env_vars.get("AI_GATEWAY_VERIFY_SSL", "true").lower()
    return val not in ("false", "0", "no")
Confidence
94% confidence
Finding
The script allows TLS certificate verification to be disabled via shared configuration, which can expose the Authorization bearer token and device live-stream traffic to man-in-the-middle attacks. Because this skill returns live playback links for device feeds, interception or tampering could lead to unauthorized surveillance access or credential compromise, making the context more sensitive than a generic API client.

Static analysis

No suspicious patterns detected.