Back to skill

Security audit

仙宫云GPU管家

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Xiangongyun cloud-management client, but it can perform destructive and billing-related actions while handling credentials in ways users should review carefully.

Install only if you intend to let an agent manage real Xiangongyun cloud resources. Use a least-privilege token if available, keep the token outside shared or version-controlled directories, verify the API base URL before use, avoid passing passwords or private keys on the command line, and require manual confirmation before any destroy, shutdown-destroy, save-and-destroy, GPU-release, deployment, or recharge-order action.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/xiangongyun_api.py:41
Finding
Unvalidated API Endpoint Can Receive Bearer Tokens and Deployment Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/xiangongyun_api.py:41`, `scripts/xiangongyun_api.py:46-51`, `scripts/xiangongyun_api.py:64-77`, `scripts/xiangongyun_api.py:138-141`; `config/config.yaml:4-7` **Vulnerability Type**: Unvalidated credential transmission destination **Risk Level**: High ### Vulnerable Code ```python # scripts/xiangongyun_api.py:41 BASE_URL = config.get("api", {}).get( "base_url", "https://api.xiangongyun.com" ) ``` ```python # scripts/xiangongyun_api.py:46-51 def __init__(self): self.api_key = self._get_api_key() self.headers = { "Authorization": "Bearer " + self.api_key, "Content-Type": "application/json" } ``` ```python # scripts/xiangongyun_api.py:64-77 def _request( self, method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None ) -> Dict[str, Any]: """发送 HTTP 请求""" url = f"{BASE_URL}{endpoint}" try: if method.upper() == "GET": response = requests.get( url, headers=self.headers, params=params, timeout=30 ) elif method.upper() == "POST": response = requests.post( url, headers=self.headers, json=data, timeout=30 ) ``` ```python # scripts/xiangongyun_api.py:138-141 if password: data["password"] = password return self._request("POST", "/open/instance/deploy", data=data) ``` ```yaml # config/config.yaml:4-7 api: base_url: "https://api.xiangongyun.com" # Replace the access_token below with the Xiangongyun API access token. access_token: "YOUR_ACCESS_TOKEN_HERE" ``` ### Technical Analysis The API destination is read directly from a mutable configuration file without validating its scheme, hostname, port, or origin. The same request logic attaches the bearer token to every request. Deployment requests can also carry a p ...[truncated 2239 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin production requests to `https://api.xiangongyun.com` rather than accepting an unrestricted configuration value. 2. If custom endpoints are required, parse the URL with `urllib.parse.urlparse` and enforce: - The `https` scheme. - An explicit hostname allowlist. - Approved ports only. - No embedded username or password. - No unexpected path prefix, query, or fragment. 3. Disable redirects for authenticated calls with `allow_redirects=False`, or validate every redirect destination before forwarding credentials. 4. Separate production and development configurations. Require an explicit development flag before permitting non-production endpoints, and never reuse production tokens in development. 5. Protect configuration ownership and permissions so that untrusted users cannot change the destination. 6. Use a narrowly scoped API token where the service supports scoped credentials, separating read-only, resource-management, destructive, and financial permissions. 7. Add automated tests confirming that HTTP URLs, lookalike domains, URL user-info components, and unapproved ports are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/xiangongyun_api.py:263
Finding
API Token, Password, and SSH Key Material Use Insecure Plaintext Input Channels<![CDATA[ ## Vulnerability Details **File Location**: `config/config.yaml:4-7`; `scripts/xiangongyun_api.py:54-61`, `scripts/xiangongyun_api.py:263-264`; `SKILL.md:34` **Vulnerability Type**: Plaintext secret storage and command-line credential exposure **Risk Level**: Medium ### Vulnerable Code ```yaml # config/config.yaml:4-7 api: base_url: "https://api.xiangongyun.com" # Replace the access_token below with the Xiangongyun API access token. access_token: "YOUR_ACCESS_TOKEN_HERE" ``` ```python # scripts/xiangongyun_api.py:54-61 def _get_api_key(self) -> str: """从 config.yaml 获取 API 令牌""" api_key = config.get("api", {}).get("access_token") if not api_key or api_key == "YOUR_ACCESS_TOKEN_HERE": raise ValueError( f"缺少仙宫云 API 令牌。请在 {CONFIG_FILE} 中配置有效的 access_token。" ) return api_key ``` ```python # scripts/xiangongyun_api.py:263-264 parser.add_argument("--ssh-key", help="SSH 密钥") parser.add_argument("--password", help="密码") ``` The documented invocation in `SKILL.md:34` directs users to provide these secrets as command-line values: ```bash python scripts/xiangongyun_api.py --action deploy_instance \ --name <instance-name> \ --gpu-count <GPU-count> \ --image <image-name> \ [--data-center <data-center>] \ [--ssh-key <SSH-key>] \ [--password <password>] ``` ### Technical Analysis The API token is expected to be placed directly in a project configuration file. Unless strict external permissions and repository exclusions are applied, that token can be exposed through source-control history, backups, artifact packaging, file sharing, or access by other local users. Passwords and SSH key material are accepted as command-line arguments. Command-line secrets can be retained in shell history, copied into terminal logs, captured by process-monitoring software, or exposed through process metadata to users with sufficient local visibility. This handling exceeds the minimum exposure necessary to submit deplo ...[truncated 1415 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Retrieve the API token from a supported secret manager or protected environment variable instead of a project file. 2. If file-based credentials must be supported: - Store them outside the project tree. - Require restrictive permissions, such as owner read/write only. - Reject overly permissive credential files. - Include local secret files in `.gitignore`. - Distribute only a placeholder configuration template. 3. Prompt for passwords interactively with `getpass.getpass()` so they do not appear in command history or process arguments. 4. Accept an SSH public-key file path instead of raw key material, then read the file internally. The deployment API should ordinarily receive only a public key, never a private key. 5. Permit secrets through standard input or inherited file descriptors for noninteractive automation. 6. Document token rotation and immediate revocation procedures. 7. Use separate, least-privilege tokens for read-only and destructive or financial operations where the provider supports that separation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/xiangongyun_api.py:355
Finding
Sensitive API Response Fields Are Printed Without Redaction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/xiangongyun_api.py:355-356`; sensitive response fields documented at `references/api_reference.md:61-70` **Vulnerability Type**: Sensitive information exposure through terminal, agent, and automation output **Risk Level**: Medium ### Vulnerable Code ```python # scripts/xiangongyun_api.py:355-356 # Output the result print(json.dumps(result, ensure_ascii=False, indent=2)) ``` The project's API reference documents that instance responses may contain sensitive fields: ```text # references/api_reference.md:61-70 ssh_key SSH key ssh_port SSH port ssh_user SSH user password Password jupyter_token Jupyter token jupyter_url Jupyter URL xgcos_token XG COS token xgcos_url XG COS URL ``` ### Technical Analysis Every API response is serialized and printed in full. No response-field filtering, secret classification, masking, or output-mode distinction is applied. According to the bundled API reference, instance list and instance detail responses can contain passwords, SSH key data, Jupyter tokens, and XG COS tokens. Consequently, ordinary read operations such as `list_instances` or `get_instance` can place active credentials in terminal scrollback, CI logs, agent transcripts, orchestration logs, or monitoring systems. Returning useful instance information is necessary for the declared functionality, but exposing credential fields by default is not. The client should minimize output to the fields needed for the user's requested operation and require an explicit secure opt-in before displaying secrets. ### Attack Path 1. A user or agent invokes `list_instances` or `get_instance`. 2. The Xiangongyun API returns an instance object containing credential-bearing fields. 3. The script serializes the complete object without redaction. 4. The output is retained in terminal history, an agent conversation, CI output, task-runner logs, or centralized logging. 5. A ...[truncated 777 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Recursively redact fields whose names indicate sensitive content, including: - `authorization` - `access_token` - `password` - `ssh_key` - `jupyter_token` - `xgcos_token` - Other fields ending in `_token`, `_secret`, `_key`, or `_password` 2. Prefer operation-specific output schemas that include only the fields required for normal use. 3. Make secret display an explicit option such as `--show-secrets`, accompanied by a clear warning. 4. Refuse secret display when output is being sent to a noninteractive terminal unless the user provides a separate confirmation flag. 5. Provide a secure method to write sensitive values directly to a permission-restricted file rather than standard output. 6. Ensure exception and debug logging do not include raw response bodies or authorization headers. 7. Add tests using nested response objects to verify that sensitive fields are consistently masked. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares broad API-driven capabilities and references a Python script using network access, but it does not define any explicit tool scope such as allowed-tools or permissions. In an agent environment, this increases the chance the skill can be invoked with broader-than-necessary file or network access, making unintended outbound requests or local file reads more likely if the skill is misrouted or abused.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger condition is very broad: any user wanting to manage instances, images, or account operations may activate the skill. Because the skill supports destructive and billing-related actions, an overly permissive invocation description makes accidental or ambiguous activation more likely, especially in multi-skill agent routing where a casual infrastructure-related request could result in high-impact operations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation exposes destructive operations like destroying instances/images, releasing GPUs, and creating recharge orders, but does not require confirmation, preview, or user warning. In this context, that is more dangerous because the skill is designed for real cloud resource and payment management, so mistaken invocation could cause irreversible data loss, service disruption, or unauthorized charges.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The destroy-instance endpoint is documented as a routine operation without an explicit warning that it may irreversibly delete the instance and any unsaved data. In an agent skill context, this increases the chance that an LLM or user will invoke a destructive action without informed confirmation, leading to accidental data loss and service disruption.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The shutdown-and-destroy operation combines power-off and deletion but does not clearly state that the deletion is irreversible or that local instance state may be lost. For an autonomous or semi-autonomous agent, this ambiguity makes accidental destructive execution more likely.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Although the endpoint name implies saving an image before destruction, the documentation does not explicitly warn that the instance will still be destroyed after the save completes. Users or agents may focus on the backup aspect and miss the destructive consequence, causing unintended deletion of running resources.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The private-image destroy endpoint lacks a clear statement that image deletion is permanent and may remove a recovery or deployment artifact needed later. In this skill, deleting images can impair recovery, redeployment, or reproducibility of GPU workloads.

External Transmission

Medium
Category
Data Exfiltration
Content
if method.upper() == "GET":
                response = requests.get(url, headers=self.headers, params=params, timeout=30)
            elif method.upper() == "POST":
                response = requests.post(url, headers=self.headers, json=data, timeout=30)
            else:
                raise ValueError(f"不支持的 HTTP 方法:{method}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
`deploy_instance` includes `ssh_key` and `password` fields in the request body and transmits them to the remote API, but the script provides no user-facing warning that these sensitive values will be sent over the network. The code has generic docstrings, but no visible disclosure at the point of use or in the CLI help about handling credentials and secrets.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script exposes destructive operations such as `destroy_instance` and sends the API request immediately, but there is no confirmation prompt, warning print/log, or explicit caution in the CLI help for the irreversible effect. For a code file, destructive operations should include some form of user disclosure unless the warning is already clearly surfaced elsewhere in the skill documentation.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The file’s natural-language comments are entirely in Chinese, including the instruction for replacing the access token. For a general configuration file, this imposes a specific language without offering user opt-in or documenting that the skill is intentionally region- or locale-specific.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The file presents all natural-language documentation in Chinese and does not indicate that the user can choose another language or that the documentation is intentionally limited to a Chinese-speaking context. Per SQP-3, forcing a specific language without user opt-in can be a natural-language policy concern unless the locale restriction is clearly documented and justified.

Static analysis

No suspicious patterns detected.