Back to skill

Security audit

huawei-cloud-obs-lifecycle-management

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches OBS lifecycle management, but it installs an unverified persistent helper CLI with automatic telemetry and has safety-gate weaknesses around high-impact lifecycle changes.

Review before installing. Use only with a dedicated, bucket-scoped Huawei Cloud credential, disable telemetry if your environment treats bucket names or prefixes as sensitive, avoid `--apply` unless approval occurred elsewhere, and do not run the helper CLI installer unless you accept a persistent, remotely downloaded executable without built-in checksum/signature verification.

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/obs_lifecycle_analyzer.py:477
Finding

Lifecycle rule update confirmation relies on a stale preview

Content
View full analysis

Vulnerability Details

File Location: scripts/obs_lifecycle_analyzer.py, lines 332–354 and 477–515
Vulnerability Type: Confirmation-gate bypass through time-of-check/time-of-use inconsistency
Risk Level: High

Vulnerable Code

python
def preview(bucket: str, prefix: str = "", rule_id: str = "", days: int = 0,
            action: str = "", limit: int = 1000) -> dict:
    cfg = get_lifecycle_config(bucket)
    rules = cfg.get("Rules") or []
    objects = list_objects(bucket, prefix, limit)
    now = datetime.now(timezone.utc)
    results = []
    total = 0
    total_size = 0
    scanned = [o for o in objects if o["key"].startswith(prefix)]

    if rule_id and days == 0 and not action:
        rule = next((r for r in rules if r.get("ID") == rule_id), None)
        if not rule:
            sys.exit(f"ERROR: rule '{rule_id}' not found in bucket {bucket}")
        effective = _rule_effective_prefix(rule)
        useprefix = effective
        input_objects = [o for o in objects if o["key"].startswith(useprefix)]
        for kind, d, cls, date_iso in _rule_actions(rule):
            affected = [o for o in input_objects if _action_reached(kind, d, date_iso, o["last_modified"], now)]
python
if prefix:
    rule["Prefix"] = prefix
    if rule.get("Filter"):
        rule["Filter"]["Prefix"] = prefix

has_exp = bool(_has_meaningful_expiration(rule))
has_trans = bool(rule.get("Transitions"))

if days > 0:
    if action == "expire":
        # Explicit expiration update — only touch Expiration.
        exp = rule.get("Expiration")
        if exp:
            exp["Days"] = days
        else:
            rule["Expiration"] = {"Days": days}
    elif action == "transition":
        # Explicit transition update — only touch Transitions.
        trans = rule.get("Transitions")
        if trans:
            trans[0]["Days"] = days
        else:
            rule["Transitions"] = [{"Days": days, "StorageClass": storage_class or "COLD"}]
    elif has_trans a
...[truncated 4244 chars]
Remediation
View remediation

Remediation Suggestions

  1. Refactor preview generation so it accepts and evaluates the locally modified rule object instead of refetching the currently deployed rule.
  2. Calculate the preview from the exact configuration object that will be passed to _put_config().
  3. Display the complete pending rule or configuration alongside the affected-object summary before requesting confirmation.
  4. Bind confirmation to a digest of the pending configuration and verify that the same digest is applied after confirmation.
  5. Refetch the remote configuration immediately before writing and reject the update if it changed after the initial read, preventing concurrent updates from invalidating the reviewed merge.
  6. Add regression tests covering:
    • Prefix expansion and narrowing.
    • Shorter and longer expiration periods.
    • Expiration-to-transition and transition-to-expiration changes.
    • Storage-class changes.
    • Rules containing both expiration and transition actions.
    • Concurrent remote configuration changes.
  7. Retain the interactive confirmation gate by default and ensure --apply is used only by a caller that has independently presented and confirmed the exact pending configuration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented functionality includes installing a separate CLI and local filesystem setup that is not central to lifecycle-policy analysis itself. Users invoking a storage-policy skill may not expect binary download, local bin modification, or version-management actions, which can be abused for persistence or execution of unreviewed code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented functionality includes installing a separate CLI and local filesystem setup that is not central to lifecycle-policy analysis itself. Users invoking a storage-policy skill may not expect binary download, local bin modification, or version-management actions, which can be abused for persistence or execution of unreviewed code.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
92% confidence
Finding

The script fetches remote metadata and then downloads and extracts a remote tarball to install executable content, but it does not authenticate the payload with a signature or checksum. Although the curl | python3 usage here only parses JSON for a version string rather than directly executing remote code, the overall flow still trusts network-supplied data to select and install binaries, enabling supply-chain compromise if the endpoint, storage bucket, or transport trust is subverted.

Content

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

sh
API_URL="https://skillsapi.developer.myhuaweicloud.com/api/quality/cli/latest"
OBS_BASE="https://obs-skills-repository.obs.cn-north-4.myhuaweicloud.com/skill-quality-cli"

V=$(curl -s "${API_URL}" | python3 -c 'import sys,json;print(json.load(sys.stdin)["version"])' 2>/dev/null)
if [ -z "$V" ]; then
    echo "警告: 无法获取 skill-quality-cli 最新版本,跳过安装" >&2
    exit 0

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

The script retrieves version metadata from a remote API and then downloads an archive based on that unpinned value, but performs no checksum or signature verification before extraction and installation. This is a classic supply-chain risk: compromise of the API, storage bucket, TLS trust chain, or release pipeline could lead to arbitrary code installation on the user's machine.

Content

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

sh
API_URL="https://skillsapi.developer.myhuaweicloud.com/api/quality/cli/latest"
OBS_BASE="https://obs-skills-repository.obs.cn-north-4.myhuaweicloud.com/skill-quality-cli"

V=$(curl -s "${API_URL}" | python3 -c 'import sys,json;print(json.load(sys.stdin)["version"])' 2>/dev/null)
if [ -z "$V" ]; then
    echo "无法获取 skill-quality-cli 最新版本" >&2
    exit 1

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/obs_lifecycle_analyzer.py (reported line 193)May include surrounding context.

python
filter_prefix = f.get("Prefix")
    if filter_prefix:  # non-empty Filter.Prefix is authoritative
        return filter_prefix
    return rule.get("Prefix") or ""


def _rule_actions(rule: dict) -> list:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs use of shell commands and local file creation/editing, but it does not declare an explicit tool scope such as allowed shell/file-write permissions. This weakens containment and review because consumers cannot tell from the manifest what execution capabilities are required, increasing the chance of over-privileged execution or unsafe reuse.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest claims all operations run through the hcloud OBS passthrough, but the body also invokes Python helper scripts and direct obsutil-related flows. This inconsistency obscures the real execution path, making it harder to reason about telemetry, auditing, and what code actually runs on the host.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad generic terms such as lifecycle, expiration, storage class, and dry-run, which could cause the skill to activate in contexts beyond Huawei OBS lifecycle management. Over-broad invocation increases the chance of unintended shell execution, data access, or confusing users into running the wrong operational workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill states that quality telemetry is collected automatically, including for routine read-only commands, but it does not clearly describe what command metadata may be transmitted. In a cloud-administration context, even metadata such as bucket names, prefixes, endpoints, or operation types can be sensitive and may leak infrastructure details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide states telemetry is automatic and only briefly mentions an opt-out, but does not clearly disclose what data is collected, when it is transmitted, or the privacy/security implications. In a security-sensitive cloud administration skill, default reporting can expose operational metadata or usage patterns without informed user consent, increasing privacy and compliance risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation exposes a highly destructive command that wipes all lifecycle rules in a bucket, even though the skill description emphasizes safer single-rule create/update/delete workflows with preview and confirmation. Including a bulk-destruction path in a quick reference increases the chance an agent or operator may invoke it accidentally or misuse it, causing immediate loss of lifecycle governance across the bucket.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This skill for Huawei OBS lifecycle management includes logic to download and install an unrelated external component, skill-quality-cli, into the user's home directory. Even if intended for telemetry or quality tooling, bundling undeclared installation behavior expands the attack surface, creates an unexpected trust dependency, and can persist code outside the skill's core purpose.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The script copies downloaded binaries and Python files into ~/.local/bin and ~/.local/bin/skill-quality-cli.d, creating persistence across future sessions. This is risky because a skill execution path should not silently install persistent executables, especially when they are fetched from the network and are not directly related to lifecycle management.

Content

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

sh
tar xzf "${TMPDIR}/sqc.tar.gz" -C "${TMPDIR}"

mkdir -p ~/.local/bin/skill-quality-cli.d
cp "${TMPDIR}/skill-quality-cli" ~/.local/bin/ 2>/dev/null
cp "${TMPDIR}/skill-quality-cli.bin" ~/.local/bin/ 2>/dev/null
cp "${TMPDIR}/skill-quality-cli.d/cli_entry.py" ~/.local/bin/skill-quality-cli.d/ 2>/dev/null

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This installer downloads and installs a separate 'skill-quality-cli' component that is not necessary for OBS lifecycle management as described in the skill metadata. Introducing an unrelated executable increases the attack surface and creates a supply-chain risk, especially because the fetched version is determined remotely at install time.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

The script copies downloaded binaries and Python files into ~/.local/bin and a persistent helper directory, creating lasting execution capability in the user's environment. Because the installed artifacts originate from a remote source and are not cryptographically verified, this persistence magnifies the impact of any compromised upstream content.

Content

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

sh
curl -fsSL -o "${TMPDIR}/sqc.tar.gz" "${OBS_BASE}/v${V}/skill-quality-cli-v${V}-linux-${ARCH}.tar.gz"
tar xzf "${TMPDIR}/sqc.tar.gz" -C "${TMPDIR}"

mkdir -p ~/.local/bin/skill-quality-cli.d
cp "${TMPDIR}/skill-quality-cli" ~/.local/bin/ 2>/dev/null
cp "${TMPDIR}/skill-quality-cli.bin" ~/.local/bin/ 2>/dev/null
cp "${TMPDIR}/skill-quality-cli.d/cli_entry.py" ~/.local/bin/skill-quality-cli.d/ 2>/dev/null

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

python
"""Run `hcloud obs ...` and return stdout; raises SystemExit on failure."""
    cmd = ["hcloud", "obs"] + args
    try:
        proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
    except FileNotFoundError:
        sys.exit("ERROR: hcloud CLI not found — see references/cli-installation-guide.md")
    except subprocess.TimeoutExpired:

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation at L101 says every hcloud command in the skill must be wrapped with skill-quality-cli run and that bare hcloud calls are strictly forbidden. But earlier examples at L65-L67 and L66-L67 include bare hcloud commands after the wrapper separator, and the rule is further undermined by direct obsutil config usage at L348, creating internal documentation inconsistency about the required execution path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

Line 10 contains a mixed-language statement with Chinese text, which may violate a language/locale policy if users are not given a language option or told that the guide is intentionally region-specific. The file does not indicate any user opt-in or justification for this locale-specific wording.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The header comments describe the script as a manually triggered, non-business helper and emphasize compliance, which downplays the fact that executing it performs network access, downloads binaries, and writes executable files into ~/.local/bin. While not a direct contradiction about control flow, the documentation materially understates the script's operational impact relative to its actual behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script’s comments and user-visible status/error messages are written in Chinese, including the failure and completion outputs. For a general-purpose installer, this hard-codes a language choice without any user opt-in or documented justification that the skill is region- or language-specific.

Content

No source excerpt is available for this finding.