Back to skill

Security audit

huawei-cloud-cdn-origin-diagnosis

Security checks for vulnerabilities and agentic risk

Overview

This is a mostly read-only CDN diagnosis skill, but its origin probe can make network requests from the agent environment to private or internal addresses from CDN configuration.

Review this before installing in an environment with access to internal services. Use it only when you trust the CDN configuration and the account collaborators, and avoid running it from a sensitive network unless private, loopback, link-local, reserved, and privately resolving origin hosts are blocked or require explicit confirmation.

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

Warning
Location
scripts/origin_probe.py:128
Finding

API-Derived Origin Address Enables Blind SSRF into the Agent Network

Content
View full analysis

Vulnerability Details

File Location: scripts/origin_probe.py, lines 128–141 and 169–186
Vulnerability Type: Blind server-side request forgery (SSRF)
Risk Level: Medium

Complete Vulnerable Code

python
def check_is_private_address(host):
    """
    Check if the host is a private/loopback/link-local IP address.

    Returns:
        True if the host is a private IP literal, False otherwise.
    """
    try:
        ip = ipaddress.ip_address(host)
        return (
            ip.is_private
            or ip.is_loopback
            or ip.is_link_local
            or ip.is_reserved
        )
    except ValueError:
        # Domain name — cannot determine without resolution
        return False
python
url = "{}://{}:{}/".format(scheme, host, port)

try:
    # Try HEAD first (matching original curl -o /dev/null behavior)
    response = requests.head(
        url,
        timeout=timeout,
        allow_redirects=False,
    )

    # Fallback to GET if HEAD is not allowed (HTTP 405)
    if response.status_code == 405:
        response.close()
        response = requests.get(
            url,
            timeout=timeout,
            allow_redirects=False,
            stream=True,
        )

The data flow is established by references/task-origin-config-query.md, lines 29–44, which directs the Agent to extract origin_addr, http_port, and https_port from configs.sources[0]. references/task-origin-probe.md, lines 5–31, then directs the Agent to pass those values to origin_probe.py.

Technical Analysis

The probe accepts a cloud API-derived origin address and uses it as an HTTP or HTTPS destination. Although check_is_private_address() identifies some private, loopback, link-local, and reserved IP literals, the result is only included as informational output. It does not prevent the request.

Domain names are treated as public without resolving and validating their addresses. Consequently, a hostname that resolves to a pr ...[truncated 2395 chars]

Remediation
View remediation

Remediation Suggestions

  1. Resolve domain names before making requests and reject every resolved address that is private, loopback, link-local, reserved, multicast, or unspecified.
  2. Reject private and special-purpose IP literals rather than merely reporting is_private_address.
  3. Validate the actual connected peer address to mitigate DNS rebinding and time-of-check/time-of-use resolution changes.
  4. Prefer an explicit allowlist of user-confirmed public origin addresses.
  5. If probing private origins is an intended feature, require explicit confirmation for each private destination and run the probe in an isolated environment without access to host-local, control-plane, or metadata services.
  6. Restrict destination ports to those configured and expected for CDN origin traffic where operationally possible.
  7. Avoid the GET fallback unless it is essential. If retained, require explicit authorization or limit it to destinations that have passed all network-address controls.
  8. Add regression tests covering direct private IPs, loopback, IPv6 local addresses, link-local addresses, hostnames resolving to private addresses, mixed public/private DNS answers, and DNS rebinding scenarios.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior claims a controlled, read-only Huawei CDN diagnosis flow, but the implementation reportedly skips the control-plane verification steps and acts only as a direct network probe. This mismatch is dangerous because users and orchestrators may trust the skill with production troubleshooting while it actually performs unaudited probing, leading to misleading results, unexpected network access, and bypass of expected safety checks around account ownership and origin configuration retrieval.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill describes use of shell commands and network probing, but it does not declare an explicit tool scope such as allowed-tools or permissions. That creates an authorization gap where an agent runtime may expose broader command/network capabilities than intended, increasing the risk of command execution or outbound access beyond the documented read-only workflow.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

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

md
>
> If a user attempts to provide AK/SK directly (e.g., "my AK is xxx, SK is yyy"):
>
> - **Stop immediately** - Do not execute any commands
> - **Politely refuse** and return the following message:
>
> ```

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · references/task-origin-probe.md (reported line 166)May include surrounding context.

md
|--------------------|----------|
| `requests` library not installed | Script emits `data.error.reason=missing_library`; prompt to install via `pip install requests>=2.25`; see cli-installation-guide.md |
| Origin address is a domain that cannot be resolved | Script emits `data.error.reason=connect_failed`; report "Origin domain resolution failed"; mark ❌ Fail |
| HTTPS certificate validation failed | Script emits `data.error.reason=tls_handshake_failed`; report warning; origin may be reachable but certificate is abnormal (do not bypass verification) |
| Invalid scheme/host/port/timeout argument | Script emits `data.error.reason=invalid_*` and exits with code 2; correct the argument and retry |
| sources is empty (Step 2 already aborted) | Skip this step |

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

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

md
Ensure the IAM user has the required permissions. See [references/iam-policies.md](references/iam-policies.md) for details.

**Minimum required permissions:**

- `cdn:*:query*` — All CDN query-class actions used by this skill (`ListDomains/v2`, `ShowDomainDetailByName`, `ShowDomainFullConfig/v2`)
- `cdn:configuration:queryDomains` — List CDN domains (listed explicitly alongside the wildcard)

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

L044-L062 states that origin_probe.py always wraps output in a {result, data, error_msg} envelope and that consumers must parse fields under data. However, the timeout example at L183-L185 shows a bare object without that envelope, which directly contradicts the documented contract and could mislead downstream users of the skill.

Content

No source excerpt is available for this finding.