Back to skill

Security audit

Imou Open Multimodal Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the advertised Imou AI image analysis, but it handles sensitive images and account authority while allowing an unchecked API destination and destructive repository commands.

Review before installing. Use only official Imou HTTPS base URLs, avoid custom or HTTP IMOU_BASE_URL values, use limited-scope Imou credentials, and treat submitted face, workwear, surveillance, or Base64 image data as sensitive. Confirm repository and target IDs carefully before deletion, and prefer a pinned dependency/lockfile for requests.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
scripts/imou_client.py:23
Finding
Unrestricted API destination permits sensitive data disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/imou_client.py:23-64`; supporting configuration in `scripts/multimodal_analysis.py:36-40` **Vulnerability Type**: User-controlled network destination without transport or hostname validation **Risk Level**: High ### Vulnerable Code ```python def _get_base_url(): return os.environ.get("IMOU_BASE_URL", "").strip() or DEFAULT_BASE_URL def _build_sign(time_sec: int, nonce: str, app_secret: str) -> str: """Build sign: MD5 of 'time:{time},nonce:{nonce},appSecret:{app_secret}' (UTF-8), 32-char lowercase hex.""" raw = f"time:{time_sec},nonce:{nonce},appSecret:{app_secret}" return hashlib.md5(raw.encode("utf-8")).hexdigest() def _request(method: str, params: dict, app_id: str, app_secret: str, base_url: str = None) -> dict: """ Send one Open API request. :param method: API method name (e.g. 'accessToken', 'humanDetect'). :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=60) resp.raise_for_status() return resp.json() ``` The CLI passes the environment-controlled destination directly into the client: ```python APP_ID = os.environ.ge ...[truncated 3071 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the destination with `urllib.parse.urlsplit()` rather than concatenating an unchecked string. 2. Require the `https` scheme and reject plaintext HTTP. 3. Allowlist the documented Imou hosts: - `openapi.lechange.cn` - `openapi-sg.easy4ip.com` - `openapi-fk.easy4ip.com` - `openapi-or.easy4ip.com` 4. Permit only expected HTTPS ports, such as 443, and reject user-information components, fragments, IP literals, and unexpected base paths. 5. Set `allow_redirects=False` for sensitive POST requests. If redirects are operationally necessary, validate every redirect destination against the same allowlist before resending data. 6. Reject empty application credentials and validate token responses before using them. 7. If private or testing endpoints must be supported, require a separate explicit unsafe opt-in flag and present a warning that credentials and image data will be sent to a non-Imou server. 8. Correct `SKILL.md` so its requirement for an explicitly configured base URL is consistent with the implementation’s default behavior. 9. Document that image and biometric data must only be submitted with appropriate authorization and consent. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Runtime dependency is not pinned to a reviewed version<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1`; installation guidance in `SKILL.md:28-31` **Vulnerability Type**: Unbounded third-party dependency resolution **Risk Level**: Low ### Vulnerable Code ```text requests>=2.28.0 ``` The documented installation command is likewise unpinned: ```bash pip install requests ``` ### Technical Analysis The lower-bound-only requirement permits pip to install any current or future `requests` release selected by the configured package index. The package name is legitimate, and the audit found no evidence of typosquatting, dependency confusion, or an intentionally malicious package. Nevertheless, installation is not reproducible and does not verify package hashes. The risk is primarily associated with a compromised or incorrectly configured package index, a compromised future dependency release, or an incompatible future version. Because dependencies execute inside the Skill’s Python process, dependency compromise would inherit access to the Skill’s environment, including Imou credentials. ### Attack Path 1. The user installs dependencies using the supplied requirement or documentation command. 2. pip queries its configured package index and resolves an arbitrary version satisfying `requests>=2.28.0`. 3. A compromised index configuration or compromised future release supplies altered package code. 4. The package is installed and subsequently imported by `scripts/imou_client.py`. 5. Malicious dependency code executes in the Skill process and may access environment variables, request payloads, images, or network traffic. This path depends on an external package-index or package-release compromise; no such compromise is present in the audited project itself. ### Impact Assessment A compromised dependency would execute with the same operating-system privileges as the Skill. It could access `IMOU_APP_ID`, `IMOU_APP_SECRET`, image content, access tokens, local files available to the process, and ...[truncated 194 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` and its transitive dependencies to reviewed versions through a lock file. 2. Record cryptographic hashes and install with `pip install --require-hashes`. 3. Use a trusted, explicitly configured package index. 4. Add automated dependency vulnerability and update monitoring. 5. Test dependency updates before changing the lock file. 6. Make the installation command in `SKILL.md` use the project’s locked requirements rather than installing the latest available package directly. ]]>
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 (13)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documentation indicates access to environment secrets and outbound network use, but it does not declare any explicit tool scope such as permissions or allowed-tools. That mismatch weakens execution-time guardrails: a host agent may allow broader-than-necessary capabilities, increasing the chance that IMOU_APP_ID/IMOU_APP_SECRET or user-supplied image URLs are accessed or transmitted without a clear policy boundary. In this context the risk is elevated because the skill is specifically designed to read secrets and send data to a configurable external endpoint.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This markdown file documents APIs that send image URLs or Base64 image data along with access tokens to a remote service, which can affect user privacy and data handling. Under the markdown-specific SQP-2 criteria, the description should warn users that images and related metadata are transmitted to an external API.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The markdown describes `deleteAiDetectRepository` as a callable API but does not warn that it performs a destructive, potentially irreversible deletion of a repository. SQP-2 for markdown files requires warnings for behaviors that could affect user data or system integrity.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The file documents `deleteAiDetectTarget` without warning that it deletes stored target data from a repository. This omission leaves users unaware of a data-affecting operation that should be explicitly disclosed in markdown documentation.

External Transmission

Medium
Category
Data Exfiltration
Content
"Content-Type": "application/json",
        OPENCLAW_HEADER: OPENCLAW_HEADER_VALUE,
    }
    resp = requests.post(url, headers=headers, json=body, timeout=60)
    resp.raise_for_status()
    return resp.json()
Confidence
80% 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

Medium
Confidence
95% confidence
Finding
This code sends request bodies containing tokens and image content to a remote API via HTTP, which can expose user or system data off-host. While the module docstring describes API functionality, it does not explicitly warn users that images and authentication data are transmitted to an external service, and there is no user-facing log or confirmation at the call site.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This function performs a deletion of an AI detect repository, which is a destructive operation, but only labels it as 'Delete detect repository' without warning about irreversibility or impact. There is no confirmation prompt, visible log, or stronger cautionary documentation around the deletion behavior.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This function deletes a target from a repository, which is a destructive action, but the inline documentation does not warn about permanence or user impact. There is no confirmation prompt, user-visible log, or explanatory comment beyond the basic operation name.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code file contains a natural-language policy constraint in its module docstring: 'All descriptions and output in English.' That forces a specific language for users without offering a language choice or explaining a region-specific requirement, which matches the locale policy violation criteria.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
Confidence
96% confidence
Finding
The dependency is specified as `requests>=2.28.0`, which is not pinned to an exact version. This makes builds non-reproducible and can cause the skill to install different releases over time, including versions with newly disclosed vulnerabilities or breaking changes. In this skill, which performs network calls to an external Imou API and may handle credentials, dependency drift increases supply-chain and reliability risk.

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 `requests` is unpinned, there is no way to verify that the installed version is free from known advisories affecting some releases of the package. This is more concerning in this skill's context because it is expected to contact external services and may use API credentials, so a vulnerable `requests` version could contribute to credential exposure, request-handling flaws, or other transport/security issues depending on the deployed release.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The code reads IMOU_APP_ID and IMOU_APP_SECRET from environment variables to authenticate requests, which is access to sensitive credentials. Although this is functionally necessary, there is no explicit warning or disclosure in nearby comments or docstrings that the skill consumes credentials from the environment.

Intent-Code Divergence

Low
Confidence
94% confidence
Finding
The help text for the target add command implies the name has some role as a local label, even if the upstream API may not persist it. In implementation, cmd_target_add never reads args.name at all, so the argument is effectively unused and the documentation overstates its behavior.

Static analysis

No suspicious patterns detected.