Back to skill

Security audit

Alibaba Cloud AI Chatbot

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Alibaba Cloud chatbot-management skill that discloses its credential and OpenAPI use, though users should be careful with region choice, mutations, and the helper script's output path handling.

Install only if you intend to let the agent manage Alibaba Cloud Chatbot resources. Use least-privilege Alibaba credentials, explicitly confirm region and resource IDs before changes, and avoid passing untrusted product, version, or output-directory arguments to the metadata helper until path validation is added.

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/list_openapi_meta_apis.py:29
Finding

Unsanitized CLI Arguments Permit Output Path Traversal

Content
View full analysis

Vulnerability Details

File Location: scripts/list_openapi_meta_apis.py, lines 29-72
Vulnerability Type: Path traversal and arbitrary file creation/overwrite
Risk Level: Medium

Vulnerable Code

python
parser.add_argument("--product-code", default=DEFAULT_PRODUCT_CODE)
parser.add_argument("--version", default=DEFAULT_VERSION)
parser.add_argument("--output-dir", default=str(OUTPUT_DIR))
args = parser.parse_args()

timeout = int(os.getenv("OPENAPI_META_TIMEOUT", "20"))
output_dir = pathlib.Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

url = (
    f"https://api.aliyun.com/meta/v1/products/{args.product_code}"
    f"/versions/{args.version}/api-docs.json"
)
payload = fetch_json(url, timeout)

raw_apis = payload.get("apis", {})
if isinstance(raw_apis, dict):
    api_names = sorted(raw_apis.keys())
elif isinstance(raw_apis, list):
    names = []
    for item in raw_apis:
        if isinstance(item, dict):
            name = item.get("name") or item.get("apiName")
            if name:
                names.append(name)
        elif isinstance(item, str):
            names.append(item)
    api_names = sorted(set(names))
else:
    api_names = []

json_file = output_dir / f"{args.product_code}_{args.version}_api_docs.json"
md_file = output_dir / f"{args.product_code}_{args.version}_api_list.md"

json_file.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
md_lines = [
    f"# {args.product_code} {args.version} API List",
    "",
    f"- Source: {url}",
    f"- API count: {len(api_names)}",
    "",
]
md_lines.extend([f"- `{name}`" for name in api_names])
md_file.write_text("\n".join(md_lines) + "\n", encoding="utf-8")

Technical Analysis

The script incorporates the user-controlled --product-code and --version values directly into output filenames without validating path separators, traversal co ...[truncated 2183 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate --product-code and --version against a strict allowlist before using them in URLs or filenames. For example, permit only letters, digits, periods, underscores, and hyphens:

    python
    import re
    
    SAFE_COMPONENT = re.compile(r"^[A-Za-z0-9._-]+$")
    
    def validate_component(value: str, name: str) -> str:
        if not SAFE_COMPONENT.fullmatch(value):
            raise ValueError(f"Invalid {name}")
        return value
    
  2. Resolve the output directory and each generated file, then verify containment before writing:

    python
    output_dir = pathlib.Path(args.output_dir).resolve()
    json_file = (output_dir / f"{product}_{version}_api_docs.json").resolve()
    
    if output_dir not in json_file.parents:
        raise ValueError("Output path escapes the selected output directory")
    
  3. If arbitrary output locations are unnecessary, remove --output-dir or require the resolved directory to remain beneath output/alicloud-ai-chatbot/.

  4. Reject absolute path fragments, .. components, and both POSIX and Windows path separators explicitly.

  5. Use exclusive creation or an explicit overwrite flag when replacing existing files is not required, reducing accidental or malicious file replacement.

  6. Add tests covering ../, absolute paths, encoded separators, mixed path separators, and symlink-based output-directory escapes.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tainted flow: 'timeout' from os.getenv (line 34, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/list_openapi_meta_apis.py (reported line 23)May include surrounding context.

python
def fetch_json(url: str, timeout: int) -> dict:
    req = urllib.request.Request(url, headers={"User-Agent": "codex-skill"})
    with urllib.request.urlopen(req, timeout=timeout) as resp:
        return json.loads(resp.read().decode("utf-8"))

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented purpose is resource management for Alibaba Cloud chatbot services, but the workflow prominently performs metadata discovery, exports API inventories, and writes local artifacts. This mismatch is dangerous because operators may authorize the skill expecting routine service management while it actually performs broader documentation harvesting and persistence behavior that was not transparently disclosed.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares no explicit tool scope even though its instructions clearly rely on environment variables, local file writes, and networked OpenAPI access. That omission weakens policy enforcement and user visibility, making it easier for the skill to access credentials, contact external services, and persist artifacts without a clearly declared permission boundary.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The activation text is broad enough to trigger on many generic Alibaba Cloud configuration or troubleshooting requests, increasing the chance the skill is selected outside its narrow intended use. In a credentialed cloud-management context, over-broad invocation can lead to unnecessary API access, unintended file generation, or mutating operations being proposed in the wrong context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Allowing the skill to choose the 'most reasonable' region when ALICLOUD_REGION_ID is unset introduces an implicit policy decision that can direct credentialed API calls to the wrong region without user approval. In cloud environments, region selection affects resource scope, data locality, compliance, and the risk of mutating or enumerating unintended assets.

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 · references/sources.md (reported line 3)May include surrounding context.

md
output_dir.mkdir(parents=True, exist_ok=True)

    url = (
        f"https://api.aliyun.com/meta/v1/products/{args.product_code}"
        f"/versions/{args.version}/api-docs.json"
    )
    payload = fetch_json(url, timeout)

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 · references/sources.md (reported line 4)May include surrounding context.

md
output_dir.mkdir(parents=True, exist_ok=True)

    url = (
        f"https://api.aliyun.com/meta/v1/products/{args.product_code}"
        f"/versions/{args.version}/api-docs.json"
    )
    payload = fetch_json(url, timeout)

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 · references/sources.md (reported line 5)May include surrounding context.

md
output_dir.mkdir(parents=True, exist_ok=True)

    url = (
        f"https://api.aliyun.com/meta/v1/products/{args.product_code}"
        f"/versions/{args.version}/api-docs.json"
    )
    payload = fetch_json(url, timeout)

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

python
output_dir.mkdir(parents=True, exist_ok=True)

    url = (
        f"https://api.aliyun.com/meta/v1/products/{args.product_code}"
        f"/versions/{args.version}/api-docs.json"
    )
    payload = fetch_json(url, timeout)

Static analysis

No suspicious patterns detected.