Back to skill

Security audit

huawei-cloud-ces-eps-query

Security checks for vulnerabilities and agentic risk

Overview

This cloud-query skill needs review because malformed region input can expose an authentication token, and its installation and telemetry requirements introduce additional security concerns.

Before installing, seek fixes that validate authenticated endpoints, preserve package certificate checks, make telemetry optional and auditable, and enforce read-only operations in live tests. Use narrowly scoped read-only cloud credentials and keep secrets out of chat. SKILL_QUALITY_REPORT=0 does not prevent the wrapper from running. The evidence supports review for concrete security weaknesses, not a conclusion of intentional theft or destruction.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Error
Location
scripts/ensure_env.py
Finding

Dependency installation disables TLS certificate verification for package mirrors

Content
View full analysis

Impact

Arbitrary code execution with the invoking user's privileges, including access to credentials and files available to that account.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (24)

Tainted flow: 'request' from os.environ.get (line 681, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
99% confidence
Finding

Sending an authentication token to the legitimate cloud API is expected, but the REST URL interpolates the unvalidated --region value into its authority. For example, region 'attacker.example/' produces a URL hosted at 'ces.attacker.example', allowing an attacker controlling that domain to receive the X-Auth-Token when REST fallback is reached; read-only operation guards do not prevent this credential disclosure.

Content

Scanner excerpt · scripts/ces_eps_query.py (reported line 685)May include surrounding context.

python
request.add_header("X-Auth-Token", token)
    request.add_header("Content-Type", "application/json")
    try:
        with urllib.request.urlopen(request, timeout=60) as response:
            body = response.read().decode("utf-8")
    except urllib.error.HTTPError as exc:
        if exc.code in (401, 403):

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The decisive mismatch is the missing read-only enforcement: is_cmd_argv_safe accepts any arguments following hcloud or curl. TC_TYPE is only used for reporting; the runner does not force mutation tests to use --help, require confirmation, or add --limit=1 to CLI queries. Thus, supplied test cases can cause live writes or out-of-scope requests, although the supplied chunk does not establish that any particular such test case exists. Shell-injection protections do not enforce cloud-operation safety. The SDK helper imports v1 for every service, references an undefined Python variable named svc, and has no subsequent REST fallback after SDK failure. Report generation is a supporting implementation detail, but unrestricted live operation execution materially contradicts the declared safety boundary.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The document confirms automatic installation of a third-party telemetry tool and mandates its execution around authenticated cloud commands, expanding the trusted execution chain beyond CES/EPS queries. The dependency is disclosed in the body, contrary to the finding's 'undeclared' wording, but mandatory automatic installation creates a supply-chain exposure with potential access to cloud credentials; the specific download and filesystem behavior cannot be verified from this file alone.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This duplicates the automatic third-party installation and execution concern rather than identifying a separate vulnerability. Local installation is not inherently unsafe, but making an unrelated downloaded executable a required intermediary for credentialed cloud operations introduces a consequential trust boundary; the installer source was not provided to validate overwrite behavior or release integrity.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The mismatch is the installation and upgrade workflow for skill-quality-cli, not merely the absence of query logic in this excerpt. The declared tooling is Huawei KooCLI and the Huawei SDKs; nothing supplied connects skill-quality-cli to those query backends. The installer scripts are not included, so their internal behavior cannot be verified.

Content

No source excerpt is available for this finding.

Quality-telemetry framing progressively makes an unrelated tool mandatory for authenticated cloud commands, including credential-configuration inspection.

High
Category
Prompt Injection
Confidence
95% confidence
Finding

The instructions extend mandatory third-party wrapping to hcloud configure list, placing credential-configuration inspection inside the telemetry tool's execution boundary. Actual secret disclosure or transmission is not established, but this unnecessarily exposes a sensitive workflow to an unrelated executable; setting SKILL_QUALITY_REPORT=0 does not establish isolation from that executable.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

The installer ultimately installs executable content selected by a mutable remote manifest, with no independently trusted signature or pinned artifact identity. HTTPS and mandatory SHA-256 verification protect transport and detect artifact mismatches, but compromise of the manifest service could replace both the download URL and expected digest, causing attacker-controlled code to be installed and run if the user subsequently invokes it. Manual invocation and the absence of immediate execution reduce exposure, while the tool's optional role adds an avoidable supply-chain dependency to this read-only skill.

Content

Scanner excerpt · scripts/install_cli.sh (reported line 28)May include surrounding context.

sh
API_URL="https://skillsapi.developer.myhuaweicloud.com/api/quality/cli/latest"

manifest="$(curl -fsSL --connect-timeout 5 --max-time 20 "${API_URL}")"
v="$(printf '%s' "$manifest" | python3 -c 'import sys,json;print(json.load(sys.stdin)["version"])')"
case "$(uname -s)" in
    Linux) ;;

The test runner can execute mutating and out-of-scope cloud commands despite the manifest's read-only CES/EPS restriction.

High
Category
Excessive Agency
Confidence
99% confidence
Finding

The allowlist permits any hcloud or curl arguments without restricting services, operations, HTTP methods, or destinations, and TC_TYPE does not enforce the promised help-only handling of mutations. A malicious or accidentally unsafe test-vars.json can therefore execute mutating or out-of-scope commands using available cloud credentials; SDK fallback also lacks an operation guard. This is particularly dangerous in a skill advertised as strictly read-only, because users may run its tests against production accounts expecting no changes.

Content

No source excerpt is available for this finding.

Skill declares no tool scope ('permissions' or 'allowed-tools') but code capabilities were detected: env, file_read, network, shell.

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Mandatory telemetry tooling is unrelated to read-only CES/EPS queries.

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The skill expressly forbids bare hcloud calls and requires an unrelated telemetry wrapper, even though telemetry is unnecessary for CES/EPS queries. This gives an additional executable an opportunity to inspect command arguments, inherited credentials, and cloud responses; read-only cloud operations do not prevent confidentiality loss.

Content

No source excerpt is available for this finding.

The guide introduces quality telemetry and requires a reporting-tool wrapper unrelated to CES/EPS queries.

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The guide requires installing and running an unrelated telemetry tool around every authenticated hcloud invocation, introducing an additional executable into the cloud-query trust boundary. Such a wrapper can potentially access inherited credential environment variables, command arguments, and sensitive CES/EPS output; however, the provided file does not establish what it actually collects or transmits. The read-only scope does not prevent disclosure, and an opt-out environment variable does not remove the wrapper's execution privileges.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ces_eps_query.py (reported line 439)May include surrounding context.

python
cmd.extend(extra)
    cmd.extend(argv)
    try:
        proc = subprocess.run(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            timeout=HCLOUD_TIMEOUT, universal_newlines=True,
        )

Tainted flow: 'cmd' from os.environ.get (line 433, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/ces_eps_query.py (reported line 439)May include surrounding context.

python
cmd.extend(extra)
    cmd.extend(argv)
    try:
        proc = subprocess.run(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            timeout=HCLOUD_TIMEOUT, universal_newlines=True,
        )

Automatically installs an unrelated quality CLI outside the declared CES/EPS query workflow.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

When invoked without an existing CLI, this script automatically downloads and persistently installs executable software unrelated to the declared read-only CES/EPS query workflow, without an explicit installation-consent step. HTTPS, mandatory SHA256 verification, and archive checks reduce risk, but the manifest supplies both the download URL and expected hash, so compromise of that source could introduce attacker-controlled software for subsequent execution with the user's permissions and potential access to cloud credentials.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/ensure_cli.sh (reported line 89)May include surrounding context.

sh
echo "警告: 解压失败或 tar 包含不安全条目, 拒绝安装" >&2
        return 1
    fi
    mkdir -p ~/.local/bin/skill-quality-cli.d || { echo "警告: 创建安装目录失败" >&2; return 1; }
    [ -f "${tmp}/skill-quality-cli" ] || { echo "警告: 安装包内容缺失(skill-quality-cli)" >&2; return 1; }
    # 主二进制: 复制/可执行位失败必须显式失败(不再静默吞错)
    cp "${tmp}/skill-quality-cli" ~/.local/bin/skill-quality-cli || { echo "警告: 复制 skill-quality-cli 失败" >&2; return 1; }

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The subprocess call uses an argument list without a shell, so it does not present an evident command-injection vulnerability. However, its pip-install caller passes --trusted-host for both package mirrors, disabling normal TLS certificate verification, and installs dependencies without pinned hashes; an attacker intercepting mirror traffic could substitute a package that executes code during installation or subsequent import. This is particularly consequential for a cloud-query skill because malicious dependency code could access credentials available to the process, regardless of the skill's intended read-only behavior.

Content

Scanner excerpt · scripts/ensure_env.py (reported line 55)May include surrounding context.

python
def run_cmd(cmd, timeout=300):
    try:
        proc = subprocess.run(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            timeout=timeout, universal_newlines=True,
        )

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/install_cli.sh (reported line 78)May include surrounding context.

sh
echo "错误: 解压失败或 tar 包含不安全条目, 拒绝安装" >&2
        exit 1
    fi
mkdir -p ~/.local/bin/skill-quality-cli.d
cp "${tmp}/skill-quality-cli" ~/.local/bin/skill-quality-cli || { echo "错误: 复制 skill-quality-cli 失败" >&2; exit 1; }
chmod +x ~/.local/bin/skill-quality-cli || { echo "错误: 设置可执行位失败" >&2; exit 1; }
if [ -f "${tmp}/skill-quality-cli.bin" ]; then

The script installs an unrelated skill-quality CLI, a capability not justified by CES/EPS read-only queries.

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The script downloads a skill-quality-cli package from a quality-service endpoint (L26–L48), then installs or overwrites executable files and supporting modules under ~/.local/bin (L78–L88). Although explicitly marked as manually invoked, this persistent software-installation capability is unrelated to the declared CES/EPS query backends and is not included in the manifest's stated purpose.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/validate-skill.sh (reported line 117)May include surrounding context.

sh
# ak=..., sk=...) inside a BasicCredentials(...) call — both are
    # in-band secret-entry forms that put AK/SK on a command
    # line / SDK kwarg, contradicting the Pre-check contract:
    #   'NEVER ask the user to type or paste AK/SK in chat; user must
    #    set env vars in shell profile out-of-band and re-run.'
    # Whitelist: lines that contain the patterns inside NEVER / Do NOT
    # / 禁止 / forbidden contexts (prose warnings about the anti-pattern

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/ces_eps_query.py (reported line 539)May include surrounding context.

python
if isinstance(response, dict):
        payload = response.get(key)
    else:
        payload = getattr(response, key, None)
    payload = to_plain(payload)
    if kind == "single":
        return payload if payload is not None else {}

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/ces_eps_query.py (reported line 602)May include surrounding context.

python
"credentials": core_credentials.BasicCredentials,
        "region": core_region.Region,
        "http_config": core_http.HttpConfig,
        "client": getattr(package, spec["sdk_client"]),
        "request": getattr(package, spec["request"]),
        "region_catalog": getattr(region_module, spec["sdk_region_class"]),
        "spec": spec,

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/ces_eps_query.py (reported line 603)May include surrounding context.

python
"region": core_region.Region,
        "http_config": core_http.HttpConfig,
        "client": getattr(package, spec["sdk_client"]),
        "request": getattr(package, spec["request"]),
        "region_catalog": getattr(region_module, spec["sdk_region_class"]),
        "spec": spec,
    }

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/ces_eps_query.py (reported line 604)May include surrounding context.

python
"http_config": core_http.HttpConfig,
        "client": getattr(package, spec["sdk_client"]),
        "request": getattr(package, spec["request"]),
        "region_catalog": getattr(region_module, spec["sdk_region_class"]),
        "spec": spec,
    }

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/ces_eps_query.py (reported line 661)May include surrounding context.

python
raise ConfigError("SDK 初始化失败(region=%s):%s" % (region, exc))
    request = build_sdk_request(category, loader, params)
    try:
        response = getattr(client, spec["sdk_method"])(request)
    except Exception as exc:
        low = str(exc).lower()
        if any(p in low for p in _AUTH_PATTERNS):

Static analysis

No suspicious patterns detected.