Back to skill

Security audit

Imou Open Device Manage

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it can send Imou credentials, tokens, and device data to an arbitrary configured API URL without enforcing official HTTPS endpoints.

Install only if you trust the environment that will set IMOU_BASE_URL and can verify it points to an official Imou HTTPS API endpoint. Treat the app ID, app secret, access token, device serials, names, and status data as sensitive. The rename command changes cloud device metadata, so use it deliberately.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/imou_client.py:25
Finding

Unrestricted API Base URL Allows Sensitive Authentication and Device Data Redirection

Content
View full analysis
dict: """ Send one Open API request. :param method: API method name (e.g. 'accessToken', 'listDeviceDetailsByPage'). :param params: Request params object. :param app_id: App ID. :param app_secret: App secret for sign. :param base_url: Optional base URL; uses env IMOU_BASE_URL or default if None. :return: Full response body as dict; check result.code for '0'. """ base = base_url or _get_base_url() url = f"{base.rstrip('/')}/openapi/{method}" time_sec = int(time.time()) nonce = uuid.uuid4().hex sign = _build_sign(time_sec, nonce, app_secret) body = { "system": { "ver": "1.0", "appId": app_id, "sign": sign, "time": time_sec, "nonce": nonce, }, "id": str(uuid.uuid4()), "params": params, } headers = { "Content-Type": "application/json", OPENCLAW_HEADER: OPENCLAW_HEADER_VALUE, } resp = requests.post(url, headers=headers, json=body, timeout=30) resp.raise_for_status() return resp.json() ``` The CLI passes the environment-controlled value directly into the client: ```python APP_ID = os.environ.get("IMOU_APP_ID", "") APP_SECRET = os.environ.get("IMOU_APP_SECRET", "") BASE_URL = os.environ.get("IMOU_BASE_URL", "").strip() or "https://openapi.lechange.cn" def _ensure_token(): if not APP_ID or not APP_SECRET: print("[ERROR] Set IMOU_APP_ID and IMOU_APP_SECRET.", file=sys.stderr) ...[truncated 4094 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/imou-device-api.md (reported line 54)May include surrounding context.

md
| Field         | Type   | Description                    |
|---------------|--------|--------------------------------|
| accessToken   | String | Admin access token            |
| expireTime    | Long   | Expiry time in **seconds**    |

Token is valid for 3 days. Request a new one when it expires or when API returns TK1002.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill requires sensitive environment variables and performs outbound network requests, but it does not declare an explicit tool/permission scope such as allowed tools or permitted network destinations. This weakens enforcement and review boundaries, making it easier for a skill with code execution capability to access secrets and contact unintended endpoints, especially because IMOU_BASE_URL is fully configurable.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The _request helper sends signed HTTP POST requests containing access tokens, app identifiers, and device-related parameters to a remote API, but there is no user-facing notice, logging, or warning that data is transmitted off-system. The module docstring identifies the API client, but it does not explicitly warn users about remote transmission of credentials and device metadata.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/imou_client.py (reported line 62)May include surrounding context.

python
"Content-Type": "application/json",
        OPENCLAW_HEADER: OPENCLAW_HEADER_VALUE,
    }
    resp = requests.post(url, headers=headers, json=body, timeout=30)
    resp.raise_for_status()
    return resp.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The modify_device_name function performs a state-changing remote API call that updates device or channel names, but the code provides no confirmation prompt, logging, or explicit warning about this modification. Although the docstring describes parameters, it does not disclose to an end user that invoking this function will alter remote device configuration.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows installation of any newer version without guaranteeing a known-safe, tested release. This creates supply-chain and reproducibility risk because vulnerable or incompatible versions could be resolved in different environments, especially for a skill that manages cloud-connected devices and may handle account or device metadata.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Because the manifest does not pin a specific requests version, it is impossible to verify whether the installed package is affected by known advisories. In a device-management skill that may make authenticated HTTP requests to cloud APIs, use of a vulnerable requests release could expose credentials, session data, or request integrity depending on the deployed version.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring states that all descriptions and output are in English, which is a natural-language locale constraint. The file does not offer a user choice or opt-in for language, so this conflicts with the policy against forcing a specific language without user consent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.