Back to skill

Security audit

Payment Skill Demo

Security checks for vulnerabilities and agentic risk

Overview

This payment skill is mostly coherent, but it can initiate refunds without enforcing the approval its own metadata promises and has credential-handling weaknesses users should review before installing.

Install only if you trust this publisher and can restrict the payment credentials. Use least-privilege API keys that cannot refund unless needed, keep PAYMENT_API_URL fixed to a trusted HTTPS payment host, avoid running diagnostics where logs are shared, rotate any credentials that may have appeared in setup output, and treat refund_payment as requiring your own external approval process until the skill enforces it in code.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/payment_skill.py:220
Finding
Refund operations do not enforce the declared approval requirement<![CDATA[ ## Vulnerability Details **File Location**: `src/payment_skill.yaml:50-55`, `src/payment_skill.py:220-247`, `skill_cli.py:203-210` **Vulnerability Type**: Missing authorization and approval enforcement **Risk Level**: High ### Vulnerable Code ```yaml - name: refund_payment description: 发起退款 timeout: 10000 rate_limit: requests_per_minute: 30 requires_approval: true ``` ```python async def refund_payment(self, transaction_id: str, amount: float = None) -> Dict[str, Any]: try: logger.info(f"发起退款: {transaction_id}, 金额: {amount}") if not transaction_id: raise ValueError("交易 ID 不能为空") if amount is not None and amount <= 0: raise ValueError("退款金额必须大于 0") result = await self.api_client.refund_payment( transaction_id=transaction_id, amount=amount ) ``` ```python elif args.command == 'refund_payment': params = { 'transaction_id': args.transaction_id } if args.amount: params['amount'] = args.amount if args.reason: params['reason'] = args.reason ``` ### Technical Analysis The Skill manifest explicitly marks `refund_payment` as requiring approval, but this requirement is not enforced in the runtime implementation. The refund method validates only that a transaction identifier exists and that an optional amount is positive. It does not require an approval token, authenticated user confirmation, authorization context, or other proof that the refund was approved. The CLI also invokes the same runtime path directly. Therefore, the manifest attribute is only descriptive and does not create an effective security boundary. Authorization must be enforced at the point where the financial action is performed, rather than relying on metadata or an external caller to behave correctly. ### Attack Path 1. An attacker, compromised Agent, or unauthorized process gains permission to execute the Skill CLI ...[truncated 1013 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Enforce approval in executable runtime code before calling the payment API. - Require a short-lived, cryptographically verifiable approval token bound to: - The authenticated user or operator. - The transaction identifier. - The exact refund amount. - An expiration time. - A unique nonce to prevent replay. - Reject full or partial refunds when the approval token is absent, expired, replayed, or does not match the request. - Enforce the same authorization rule on the payment server; client-side checks must not be the only control. - Apply least-privilege credentials so the Skill cannot issue refunds unless explicitly required. - Record the approving identity, transaction, amount, timestamp, and authorization result in a tamper-resistant audit log. - Add tests that invoke the CLI and `PaymentSkill.execute()` directly and verify that unapproved refunds are denied. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/payment_api_client.py:54
Finding
Configurable API endpoint can expose bearer credentials over untrusted transport<![CDATA[ ## Vulnerability Details **File Location**: `src/config_loader.py:84-104`, `src/payment_api_client.py:54-74` **Vulnerability Type**: Insufficient destination and transport validation **Risk Level**: Medium ### Vulnerable Code ```python config = { "api_key": os.getenv("PAYMENT_API_KEY"), "api_secret": os.getenv("PAYMENT_API_SECRET"), "api_url": os.getenv("PAYMENT_API_URL"), "timeout": int(os.getenv("PAYMENT_API_TIMEOUT", "30")) if os.getenv("PAYMENT_API_TIMEOUT") else 30, } env_config = ConfigLoader.load_env_file(env_name) if not config["api_key"]: config["api_key"] = env_config.get("PAYMENT_API_KEY") if not config["api_secret"]: config["api_secret"] = env_config.get("PAYMENT_API_SECRET") if not config["api_url"]: config["api_url"] = env_config.get("PAYMENT_API_URL") if not config["api_url"]: config["api_url"] = "https://api.zlclaw.com" ``` ```python url = f"{self.api_url}/{endpoint}" signature = self._generate_signature(method, endpoint, data) timestamp = str(int(time.time())) headers = { "Authorization": f"Bearer {self.api_key}", "X-Signature": signature, "X-Timestamp": timestamp, "Content-Type": "application/json" } async with self.session.request( method, url, json=data, headers=headers, timeout=aiohttp.ClientTimeout(total=self.timeout) ) as response: ``` ### Technical Analysis `PAYMENT_API_URL` accepts an arbitrary value without validating its scheme, hostname, port, embedded credentials, or relationship to an approved payment service. Every request sends the API key in a bearer authorization header and sends signed payment information to the configured destination. Although the shipped production default is `https://api.zlclaw.com`, the code does not require HTTPS or enforce an approved-host list. The configuration includes `PAYMENT_TLS_VERIFY=true`, but the reviewed request implementation does not read or enforce that setting explicitly. This becomes exploitable when an ...[truncated 1437 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Parse the configured URL with a standard URL parser and reject every scheme except `https`. - Maintain an explicit allowlist of approved payment API hostnames and ports. - Reject URLs containing user information, fragments, unexpected paths, or nonstandard ports unless specifically required. - Ensure certificate and hostname verification remain enabled and cannot be disabled in production. - Disable automatic redirects for credential-bearing requests, or validate every redirect destination and strip sensitive headers when the authority changes. - Do not send authorization headers during health checks unless authentication is strictly required. - Use narrowly scoped, revocable credentials and rotate any credential suspected of having been sent to an untrusted endpoint. - Treat environment variables and configuration files as privileged deployment inputs and restrict who can modify them. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/diagnose.py:202
Finding
Automatic setup diagnostics disclose API credential fragments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/diagnose.py:202-224`, `scripts/setup.sh:79-85` **Vulnerability Type**: Sensitive information exposure through diagnostic output **Risk Level**: Medium ### Vulnerable Code ```python def check_environment_variables(): """检查环境变量""" print_header("环境变量检查") import os env_vars = [ "PAYMENT_API_KEY", "PAYMENT_API_SECRET", "PAYMENT_API_URL", "PAYMENT_LOG_LEVEL", ] for var in env_vars: value = os.getenv(var) if value: # 隐藏敏感信息 if "SECRET" in var or "KEY" in var: display_value = f"{value[:4]}...{value[-4:]}" else: display_value = value print_success(f"{var}: {display_value}") else: print_warning(f"{var}: 未设置") ``` ```bash echo "Running diagnostics..." if [ -f "$SCRIPT_DIR/diagnose.py" ]; then python3 "$SCRIPT_DIR/diagnose.py" else echo "Warning: diagnose.py not found, skipping diagnostics" fi ``` ### Technical Analysis The documented setup process automatically runs the diagnostic script. When payment credentials are already exported, the diagnostic script prints the first four and last four characters of each API key or secret. Partial credential disclosure is unnecessary for confirming that an environment variable is present. The output can be retained in terminal scrollback, CI/CD logs, remote build logs, support bundles, or captured setup transcripts. For credentials eight characters long or shorter, slicing can reveal all characters, potentially with overlap. ### Attack Path 1. A developer or deployment process exports `PAYMENT_API_KEY` and `PAYMENT_API_SECRET`. 2. The documented `scripts/setup.sh` installer is executed. 3. The installer automatically runs `scripts/diagnose.py`. 4. The diagnostic script prints credential prefixes and suffixes. 5. A user with access to CI logs, terminal recordings, build output, or a su ...[truncated 574 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never print any portion of an API key, secret, password, token, or encryption key. - Report only whether each sensitive variable is set, for example: ```python print_success(f"{var}: set") ``` - Avoid automatically running diagnostics that inspect sensitive configuration during installation. - Ensure CI systems redact known secret values and restrict access to setup logs. - Review and purge existing logs that may contain credential fragments. - Rotate credentials if diagnostic output has been stored in broadly accessible logs. - Add automated tests that fail if diagnostic output contains any substring of configured test credentials. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
src/security.py:116
Finding
Encryption key handling silently pads or truncates configured secrets<![CDATA[ ## Vulnerability Details **File Location**: `src/security.py:116-125` **Vulnerability Type**: Weak cryptographic key derivation and insufficient key validation **Risk Level**: Low ### Vulnerable Code ```python @classmethod def from_env(cls, env_key: str = "PAYMENT_ENCRYPTION_KEY") -> "DataEncryption": import os key_str = os.environ.get(env_key) if not key_str: raise ValueError(f"环境变量 {env_key} 未设置,生产环境必须提供加密密钥") key_bytes = key_str.encode()[:32].ljust(32, b'0') return cls(key_bytes) ``` ### Technical Analysis The constructor requires a 32-byte key, but `from_env()` transforms every nonempty input into exactly 32 bytes by truncating long values and padding short values with ASCII zero bytes. This contradicts the documented requirement for a genuine 32-byte encryption key. Short passphrases therefore produce low-entropy, predictable AES keys. Different long values sharing the same first 32 encoded bytes also produce identical keys. UTF-8 multibyte input may be truncated in the middle of an encoded character, further making the effective key different from operator expectations. The AES-GCM construction itself is appropriate in the reviewed code, and Base64 is only used to serialize ciphertext, nonce, and authentication tag. No covert transmission sink was found in `DataEncryption`. The weakness is limited to key derivation and validation. ### Attack Path 1. An operator enables encryption and configures a short value such as a human-memorable password in `PAYMENT_ENCRYPTION_KEY`. 2. `from_env()` pads the password with predictable zero bytes rather than rejecting it or applying a password-based key derivation function. 3. An attacker obtains encrypted data produced by the Skill. 4. The attacker performs an offline dictionary attack against likely passwords and applies the documented zero-padding transformation to each candidate. 5. AES-GCM authentication allows the attacker to efficiently determine when the correct key h ...[truncated 350 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require an unambiguous encoded key format, such as Base64 or hexadecimal. - Decode the configured value and reject it unless the decoded key is exactly 32 bytes. - Do not silently truncate or pad key material. - If human-readable passphrases must be supported, derive the key using a standard password-based KDF such as Argon2id, scrypt, or PBKDF2 with a unique random salt and an appropriate work factor. - Separate passphrase configuration from raw-key configuration so operators cannot confuse the two formats. - Document key generation and rotation procedures. - Add tests covering short inputs, overlong inputs, malformed encodings, and multibyte text. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is presented as providing payment functionality, but it also performs environment setup, virtual environment management, package installation, and diagnostic script execution. In combination with shell execution, this expands the trust boundary from payments into arbitrary system modification, which is especially risky in a high-security financial context.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as providing payment functionality, but it also performs environment setup, virtual environment management, package installation, and diagnostic script execution. In combination with shell execution, this expands the trust boundary from payments into arbitrary system modification, which is especially risky in a high-security financial context.

Known Vulnerable Dependency: aiohttp==3.6.3 — 16 advisory(ies): CVE-2026-54279 (aiohttp: Host-Only Cookies Become Domain Cookies After CookieJar Persistence); CVE-2026-34514 (AIOHTTP has CRLF injection through multipart part content type header constructi); CVE-2026-34517 (AIOHTTP has late size enforcement for non-file multipart fields causes memory Do) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
Pinning aiohttp to 3.6.3 introduces a dependency version with multiple published advisories, including request parsing and multipart handling issues that can enable denial of service, header injection, or cookie-handling weaknesses. In a payment-related skill, an HTTP client is likely used for API calls and possibly webhook or multipart interactions, increasing the risk that vulnerable library behavior could affect sensitive payment workflows.

Known Vulnerable Dependency: pydantic==1.8.2 — 2 advisory(ies): CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2024-3772 (Pydantic regular expression denial of service)

High
Category
Supply Chain
Confidence
94% confidence
Finding
Pydantic 1.8.2 is flagged for a regular-expression denial-of-service issue, which can allow crafted input to trigger excessive CPU consumption during validation. In a payment skill that may validate user-supplied or partner-supplied data, this can be abused to degrade availability or stall request processing.

Known Vulnerable Dependency: cryptography==3.4.8 — 16 advisory(ies): CVE-2023-50782 (Python Cryptography package vulnerable to Bleichenbacher timing oracle attack); GHSA-537c-gmf6-5ccf (Vulnerable OpenSSL included in cryptography wheels); GHSA-5cpq-8wj7-hf2v (Vulnerable OpenSSL included in cryptography wheels) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding
cryptography 3.4.8 is associated with multiple advisories, including cryptographic weaknesses and vulnerable bundled OpenSSL components in some distributions. Because this skill is payment-related and likely handles secrets, tokens, signatures, or encrypted transport, outdated cryptography dependencies materially increase the chance of compromise of sensitive financial data or trust boundaries.

Known Vulnerable Dependency: pycryptodome==3.10.4 — 2 advisory(ies): CVE-2023-52323 (PyCryptodome and pycryptodomex side-channel leakage for OAEP decryption); CVE-2023-52323 (PyCryptodome and pycryptodomex side-channel leakage for OAEP decryption)

High
Category
Supply Chain
Confidence
96% confidence
Finding
pycryptodome 3.10.4 is flagged for an OAEP decryption side-channel issue that may leak information during cryptographic operations. In a payment context, side-channel leakage in decryption or key-handling code is especially serious because it can undermine confidentiality of transaction data, tokens, or private-key-backed operations.

Known Vulnerable Dependency: pytest==6.2.5 — 2 advisory(ies): CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)

High
Category
Supply Chain
Confidence
80% confidence
Finding
pytest 6.2.5 is reported with a tmpdir-handling vulnerability, but this dependency is listed under test tooling rather than production runtime libraries. That makes the issue less dangerous in normal deployment, though it can still matter in CI environments or shared build systems where untrusted test inputs or filesystem interactions are possible.

Known Vulnerable Dependency: aiohttp==3.9.5 — 16 advisory(ies): CVE-2026-54279 (aiohttp: Host-Only Cookies Become Domain Cookies After CookieJar Persistence); CVE-2026-34514 (AIOHTTP has CRLF injection through multipart part content type header constructi); CVE-2026-34517 (AIOHTTP has late size enforcement for non-file multipart fields causes memory Do) +13 more

High
Category
Supply Chain
Confidence
96% confidence
Finding
The file pins aiohttp==3.9.5, and the provided advisories indicate multiple known vulnerabilities affecting this version, including cookie handling, header injection, and denial-of-service conditions. In a payment-related skill, an HTTP client/server library flaw is especially concerning because it may affect request handling, session integrity, or service availability in a sensitive transaction context.

Known Vulnerable Dependency: cryptography==42.0.5 — 11 advisory(ies): GHSA-537c-gmf6-5ccf (Vulnerable OpenSSL included in cryptography wheels); CVE-2024-12797 (Vulnerable OpenSSL included in cryptography wheels); GHSA-h4gh-qq45-vh27 (pyca/cryptography has a vulnerable OpenSSL included in cryptography wheels) +8 more

High
Category
Supply Chain
Confidence
95% confidence
Finding
cryptography==42.0.5 is reported as bundling vulnerable OpenSSL components in some distributions. In a payment skill, cryptographic library weaknesses are particularly serious because they can undermine TLS protections, certificate validation, or other security-sensitive operations used to protect payment data.

Known Vulnerable Dependency: pytest==8.2.0 — 2 advisory(ies): GHSA-6w46-j5rx-g56g; PYSEC-2026-1845

High
Category
Supply Chain
Confidence
80% confidence
Finding
pytest==8.2.0 is flagged by advisories, so the dependency is technically vulnerable. However, as a test-only dependency, its exposure is usually limited to development and CI environments rather than production runtime, which substantially reduces direct risk to end users unless CI processes handle untrusted input or secrets insecurely.

Credential Access

High
Category
Privilege Escalation
Content
配置字典
        """
        config_dir = ConfigLoader.get_config_dir()
        env_file = config_dir / f"{env_name}.env"
        
        if not env_file.exists():
            logger.warning(f"配置文件不存在: {env_file}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises executable setup scripts, CLI invocation, environment variable use, and networked payment operations, but it does not declare an explicit permission or allowed-tools scope. In a payment-related skill, undeclared access to shell, environment, file reads, and network increases the chance that a host agent grants broader capabilities than the user expects, weakening least-privilege controls.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The manifest description is written entirely in Chinese and presents the skill as a general payment solution, with no indication that the Chinese locale is optional or region-specific. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents a refund operation without clearly warning that it causes real financial state changes and may be irreversible or require authorization checks. In a payment context, omission of such warning can lead to accidental misuse by an agent or user, resulting in unintended monetary loss or fraudulent refund attempts.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The manifest says the skill provides secure, reliable payment functionality, but this file is an environment diagnostic tool that checks Python versions, dependencies, project structure, requirements files, and environment variables. That behavior is operational tooling for development/setup rather than implementing payment features.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring and all user-facing messages in this script are written exclusively in Chinese, indicating a fixed language choice for the skill experience. The provided file does not offer a language/locale option or document a region-specific reason for restricting output to Chinese, which matches the language-policy violation criteria.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print_header("pip 版本检查")
    
    try:
        result = subprocess.run(
            [sys.executable, "-m", "pip", "--version"],
            capture_output=True,
            text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The script reads payment-related secrets from environment variables and prints masked portions to stdout. Even partial disclosure of API keys/secrets can leak sensitive metadata into logs, terminals, CI output, or support screenshots, and this capability is broader than necessary for a diagnostic helper in a payment context.

Known Vulnerable Dependency: python-dotenv==0.19.0 — 2 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)

Medium
Category
Supply Chain
Confidence
88% confidence
Finding
python-dotenv 0.19.0 has an advisory related to symlink following during set_key operations, which can lead to unintended file overwrite if an attacker can influence the .env path or filesystem layout. In deployment or setup tooling for a payment skill, this is dangerous because environment files often hold secrets and configuration for payment credentials.

Known Vulnerable Dependency: python-dotenv==1.0.1 — 2 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)

Medium
Category
Supply Chain
Confidence
89% confidence
Finding
python-dotenv==1.0.1 is flagged with advisories related to symlink following and unsafe file overwrite behavior in set_key. While dotenv is often used during development, if this skill uses it in operational tooling or writes .env files in untrusted directories, an attacker could abuse filesystem links to overwrite unintended files.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code file contains natural-language user-facing strings entirely in Chinese, including the module docstring and usage examples, with no indication that Chinese is optional or that the skill is region-specific. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
This code file uses Chinese-only natural-language documentation and inline comments throughout, including the module docstring and method docstrings, without any indication that the skill is region-specific or that users may opt into this locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
All human-readable docstrings and log/error messages in the file are written exclusively in Chinese, which imposes a specific language on users and operators. The file does not indicate that the locale is region-specific or provide any mechanism for language choice or opt-in.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The refund_payment method triggers a refund via a POST request, which is a safety-critical and potentially irreversible financial operation. While the function has an internal docstring, there is no visible confirmation prompt, user-facing log/print, or explicit warning about the impact of issuing a refund.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill exposes a refund operation that can be invoked directly once the caller supplies a transaction_id, without any built-in confirmation step, re-authentication, or explicit safeguard for a destructive financial action. In a payment skill, refunds are safety-critical because accidental or prompt-manipulated invocation can cause unauthorized fund reversals and business loss.

Static analysis

No suspicious patterns detected.