Back to skill

Security audit

Multi-Cloud Docs/API Benchmark

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the advertised documentation benchmark, but it asks users to configure cloud credentials it does not appear to need and its URL filtering can be bypassed to make the runner fetch unintended internal or arbitrary URLs.

Review before installing. Use it only in a sandboxed environment with restricted outbound network access, do not provide Alibaba Cloud access keys for this documentation-only benchmark unless the skill is revised to justify and use read-only credentials, and avoid running it with links supplied by untrusted parties.

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/benchmark_multicloud_docs_api.py:107
Finding

Insufficient URL Validation Enables Server-Side Request Forgery

Content
View full analysis
bool: low = url.lower() return any(d in low for d in domains) ``` The weak validation is applied to links supplied through command-line arguments: ```python manual = getattr(args, f"{p.key}_links", "").strip() if manual: links = [x.strip() for x in manual.split(",") if x.strip()] links = [u for u in links if domain_allowed(u, p.domains)] source_tier = "L0" confidence = "high" if links else "low" notes = ["Using user-pinned official links."] ``` Accepted URLs are subsequently fetched: ```python def classify_links(links: list[str], max_fetch: int = 3) -> dict[str, bool]: chunks = ["\n".join(links).lower()] for url in links[:max_fetch]: try: html = fetch_text(url, timeout=12).lower() except Exception: continue ``` The request function uses `urllib.request.urlopen`, which follows redirects without validating each resulting destination: ```python def fetch_text(url: str, timeout: int = 20) -> str: req = urllib.request.Request( url, headers={ "User-Agent": "Mozilla/5.0 (Codex MultiCloud Benchmark)", "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8", }, ) with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.read().decode("utf-8", errors="ignore") ``` ### Technical Analysis The `domain_allowed` function searches the complete URL for an approved domain substring. It does not parse the URL or verify that the approved domain is the actual destination hostname. Consequently, a URL may contain an approved domain in its user-information, path, query string, or an attacker-co ...[truncated 2968 chars]
Remediation
View remediation
bool: return any( host == domain or host.endswith("." + domain) for domain in domains ) ``` 5. Resolve the hostname and reject every loopback, private, link-local, multicast, unspecified, and reserved address using Python's `ipaddress` module. Validate all returned DNS addresses, not only the first one, to reduce DNS rebinding exposure. 6. Reject unexpected ports or maintain a narrow allowlist such as TCP 443. 7. Disable automatic redirects or install a redirect handler that validates the scheme, hostname, port, and resolved IP address for every redirect destination before following it. 8. Apply the same validation immediately before each network request rather than relying only on filtering performed earlier in the workflow. 9. Impose response-size limits and restrictive connection/read timeouts to reduce resource-exhaustion risk. 10. Where possible, route outbound traffic through an egress proxy that independently blocks loopback, private, link-local, metadata, and unauthorized external destinations. 11. Add regression tests for user-information confusion, malicious subdomains, domain names in paths and query strings, encoded hostnames, IPv4 and IPv6 literals, redirects to private addresses, alternate numeric IP representations, and DNS records resolving to restricted address ranges. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documents execution of Python scripts that perform file writes and official-domain web discovery, but it does not declare any explicit tool scope such as allowed tools or permissions. This creates a mismatch between documented behavior and enforceable boundaries, increasing the risk that an agent executes with broader filesystem or network access than intended.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The prerequisites section asks for Alibaba Cloud credentials and references 'mutating operations' even though the skill is described as a documentation benchmarking workflow. Requesting cloud credentials without a clear operational need expands the attack surface and can mislead an agent or user into supplying sensitive access for a task that should only require public documentation retrieval.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The default prompt uses a very broad invocation phrase that can be triggered by ordinary requests to compare cloud documentation, without clear guardrails or activation boundaries. This increases the chance of unintended skill activation and scope overlap with general-purpose user queries, which can cause the agent to invoke this capability when the user did not explicitly intend to call the skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest file defines trigger keywords such as "llm platform" and "模型服务", which are generic phrases that could appear in ordinary discussion about AI services rather than specifically requesting this preset. The file does not provide exclusion conditions, negative examples, or tighter scope constraints to distinguish when the preset should or should not activate.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/benchmark_multicloud_docs_api.py (reported line 40)May include surrounding context.

python
"skills/platform/docs/alicloud-platform-multicloud-docs-api-benchmark/references/scoring.json"
)
GCP_DISCOVERY_APIS = "https://discovery.googleapis.com/discovery/v1/apis"
GITHUB_API_SEARCH_CODE = "https://api.github.com/search/code?q="

DEFAULT_SCORING_PROFILE = {
    "link_cap": 8,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The Accept-Language header is hard-coded to prefer en-US, then en, then zh-CN for fetched content. This imposes a locale preference in the skill behavior without opt-in, which matches the policy category for language or locale constraints.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/benchmark_multicloud_docs_api.py (reported line 321)May include surrounding context.

python
def alicloud_openapi_signals(product: str) -> dict[str, Any]:
    try:
        zh = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=ZH_CN")
        en = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=EN_US")
    except Exception:
        return {"resolved": False}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/benchmark_multicloud_docs_api.py (reported line 322)May include surrounding context.

python
def alicloud_openapi_signals(product: str) -> dict[str, Any]:
    try:
        zh = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=ZH_CN")
        en = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=EN_US")
    except Exception:
        return {"resolved": False}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/benchmark_multicloud_docs_api.py (reported line 366)May include surrounding context.

python
def alicloud_openapi_signals(product: str) -> dict[str, Any]:
    try:
        zh = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=ZH_CN")
        en = fetch_json("https://api.aliyun.com/meta/v1/products.json?language=EN_US")
    except Exception:
        return {"resolved": False}

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code fetches content from DuckDuckGo, Google, GitHub, and Alibaba Cloud endpoints, and the queried product keyword is incorporated into those requests. While network access is central to the script's purpose, the file lacks any explicit docstring, comment, or user-facing notice that running it will transmit search terms to third-party services.

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

python
preset_seeds = [str(x) for x in preset_seeds_raw if isinstance(x, str)]
        preset_seeds = [u for u in preset_seeds if domain_allowed(u, p.domains) or "github.com" in u.lower()]

        manual = getattr(args, f"{p.key}_links", "").strip()
        if manual:
            links = [x.strip() for x in manual.split(",") if x.strip()]
            links = [u for u in links if domain_allowed(u, p.domains)]

Static analysis

No suspicious patterns detected.