Back to skill

Security audit

海康云眸设备通道管理

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches its stated Hik-Cloud channel-management purpose, but its credential and token handling is too broadly scoped for automatic installation.

Review this skill before installing in any shared or production environment. Only use trusted HTTPS Hik-Cloud endpoints, avoid passing bearer tokens on the command line, protect or disable the token cache where possible, and rotate credentials if the skill has been run with an untrusted custom base URL.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/hik_open_device_channel_management.py:109
Finding

Unrestricted Base URL Can Exfiltrate Client Credentials and Bearer Tokens

Content
View full analysis
str: if explicit_base_url: return normalize_base_url(explicit_base_url) env_base_url = os.getenv(BASE_URL_ENV_VAR) if env_base_url: return normalize_base_url(env_base_url) return DEFAULT_BASE_URL ``` ```python def fetch_access_token( base_url: str, client_id: str, client_secret: str, timeout: float, ) -> dict[str, Any]: status, payload = http_json_request( method="POST", url=base_url.rstrip("/") + TOKEN_PATH, headers=None, timeout=timeout, form_body={ "client_id": client_id, "client_secret": client_secret, "grant_type": "client_credentials", "scope": "app", }, ) if status != 200 or "access_token" not in payload: error_code, error_message = summarize_error_payload(payload) raise ApiError( "failed to fetch access token: " f"http={status}, code={error_code}, message={error_message}" ) expires_in = int(payload.get("expires_in", 0)) return { "access_token": payload["access_token"], "expires_in": expires_in, "expires_at": time.time() + max(expires_in, 0), "token_type": payload.get("token_type", "bearer"), } ``` ```python def resolve_access_token( base_url: str, timeout: float, cache_file: Path, explicit_token: str | None, ) -> tuple[str, bool]: if explicit_token: return explicit_token, False env_token = os.getenv("HIK_OPEN_ACCESS_TOKEN") if env_token: return env_tok ...[truncated 5290 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/hik_open_device_channel_management.py:126
Finding

Bearer Token Cache Is Written Without Explicit Restrictive Filesystem Protections

Content
View full analysis
None: cache_file.parent.mkdir(parents=True, exist_ok=True) cache_file.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") ``` ### Technical Analysis The cache contains a plaintext bearer token and its expiration metadata. The script creates the parent directory and writes the file using default filesystem behavior, without explicitly enforcing owner-only permissions. The resulting permissions depend on the process umask and the state of any pre-existing directory or file. In permissively configured environments, other local users or processes may be able to read the cached bearer token. The code also does not verify ownership, reject symbolic links, or use an atomic no-follow file creation mechanism. Consequently, a pre-existing attacker-controlled cache path may cause the write to follow a symbolic link where filesystem permissions allow it. The default location under the user's home directory reduces exposure on normally configured systems, but it does not guarantee secure permissions. The `--token-cache-file` option also allows callers or wrappers to select locations with weaker access controls. ### Attack Path 1. The Skill runs in a multi-user environment, shared runtime, permissively configured container, or account with a weak umask. 2. The attacker obtains access to the cache directory or prepares an attacker-readable file or symbolic link at the configured cache path. 3. The existing token expires or is absent, causing the script to request a new access token. 4. `save_token_cache` writes the bearer token as plaintext without explicitly applying mode `0600`, checking ownership, or rejecting a symbolic link. ...[truncated 792 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向海康云眸设备通道管理的功能性技能,但当前提供的代码片段仅是测试/契约校验代码,检查技能文档是否声明了 skillKey、环境变量、token 暴露策略、缓存路径以及若干字段说明。其主要用途是文档与约定验证,而不是调用外部平台 API 或执行通道管理。即使测试内容间接提到这些能力,也没有实际实现对应行为,因此代码实际行为与声明用途存在明显不一致。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
85% confidence
Finding

The skill explicitly supports passing an access token via a command-line argument and describes token caching in a local file. Command-line arguments can be exposed through process listings, shell history, logs, or telemetry, and local token cache files can be read by other processes/users if permissions are weak, making credential theft more likely in shared or sandboxed environments.

Content

Scanner excerpt · SKILL.md (reported line 127)May include surrounding context.

md
通用参数:

- `--base-url`:显式指定接口域名,优先级高于环境变量
- `--access-token`:显式指定 access token
- `--timeout`:请求超时秒数,默认 `20`
- `--token-cache-file`:token 缓存文件,默认 `~/.cache/hik_open/token.json`
- `--format`:`text` 或 `json`

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 · scripts/hik_open_device_channel_management.py (reported line 204)May include surrounding context.

python
if status != 200 or "access_token" not in payload:
        error_code, error_message = summarize_error_payload(payload)
        raise ApiError(
            "failed to fetch access token: "
            f"http={status}, code={error_code}, message={error_message}"
        )
    expires_in = int(payload.get("expires_in", 0))

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares capabilities that involve reading environment variables, writing a token cache file, and making network requests, but it does not explicitly constrain tool scope with permissions or allowed-tools metadata. In an agent environment, missing scope declarations can allow broader-than-expected execution and secret exposure through env/network/file operations, especially since the skill handles API credentials and cached tokens.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file presents the skill’s description, usage instructions, and operational rules entirely in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file describes OAuth token retrieval, automatic refresh, and use of sensitive environment variables such as client secrets, but it does not include any warning about privacy, credential handling, or outbound authenticated API calls. Under the markdown variant of SQP-2, descriptions should warn users when behavior could affect privacy or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script persists OAuth access tokens to a predictable file under the user's home directory without setting restrictive permissions or warning the operator. On multi-user systems or misconfigured environments, another local process or user could read the cached token and reuse it to access the Hik-Cloud API as the victim.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This code asserts the presence of specific Chinese-language phrases in the skill documentation, which indicates the skill contract may require a fixed language/locale. Under the policy, forcing a specific language without offering user choice can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill presents its name and description in Chinese, but the default prompt is hardcoded in English. This can impose a language choice implicitly rather than offering the user a locale option, which matches the policy concern about forcing a specific language without opt-in.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/hik_open_device_channel_management.py (reported line 79)May include surrounding context.

python
return

    for method_name in ("SetConsoleOutputCP", "SetConsoleCP"):
        method = getattr(kernel32, method_name, None)
        if not callable(method):
            continue
        try:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

When force_refresh is enabled, the code deletes the existing token cache file via unlink(). There is no visible confirmation prompt or user-facing message indicating that a local file will be removed, and the surrounding code does not document this deletion behavior.

Content

No source excerpt is available for this finding.