T09 · Insecure Skill Coding Practices
- Location
server/server.py:173- Finding
Payment Verification Fails Open When Credential Decryption Fails
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly does what it says, but its payment and local data handling are insecure enough that users should review it before installing.
Install only if you are comfortable with a review-required paid-skill implementation. Do not put sensitive business or personal information in prompts, and do not rely on this package's payment checks for real billing until fail-closed verification, server-side receipt validation, secret removal, restrictive file permissions, and order path validation are fixed.
server/server.py:173Payment Verification Fails Open When Credential Decryption Fails
server/server.py:17Hardcoded Symmetric Key Allows Forgery of Successful Payment Credentials
scripts/file_utils.py:13Unvalidated Order Identifier Permits Reads Outside the Order Directory
scripts/file_utils.py:23Payment and Order Data Are Stored Without Explicit Restrictive Permissions
A payment-gated service becomes security-relevant if access is granted when credential decryption or parsing fails. Fail-open payment verification lets attackers bypass the paywall and may also indicate unsafe handling of authentication material, undermining both revenue protection and trust in the credential-validation path.
A payment-gated service becomes security-relevant if access is granted when credential decryption or parsing fails. Fail-open payment verification lets attackers bypass the paywall and may also indicate unsafe handling of authentication material, undermining both revenue protection and trust in the credential-validation path.
The skill description says payment verification is required before execution, but the code falls back to generate_local(question) whenever the backend request fails or verification cannot be completed. That means a user can still obtain the paid service output during backend outage, network failure, or by intentionally disrupting verification, which bypasses the paywall and undermines business controls.
The payment gate is enforced only by decrypting a client-supplied credential and checking whether the decrypted JSON says payStatus=SUCCESS. There is no signature, MAC, server-side receipt validation, or binding to the stored order, so anyone who can produce a locally decryptable blob can mark payment as successful and obtain the paid result without actually paying.
The payment gate is effectively bypassed because any credential decryption or parsing failure falls through to pay_status = "SUCCESS". An attacker can submit malformed or random credential data and still receive paid results, directly defeating the stated requirement that payment verification must occur before execution.
Without declared permissions the skill's intent is opaque and cannot be validated.
The core description is entirely in Chinese and presents the skill behavior and usage in that language, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking locale. This can violate language/locale policy when a skill imposes a specific language without user opt-in.
The code transmits the user's question, order number, and payment credential to a backend over plain HTTP, which provides no transport encryption. On any non-localhost deployment, this would expose potentially sensitive data to interception or manipulation; even in local setups, the pattern is unsafe and can normalize insecure handling of credentials.
The file presents its purpose and user-facing interface entirely in Chinese, beginning with the module docstring on L02 and continuing through other user-facing strings. The policy requires avoiding a forced language/locale unless the skill offers user choice or clearly documents a justified region-specific constraint, which is not present here.
The script transmits the user's question to a create-order API over plain HTTP, not HTTPS, and does so without an explicit privacy warning. This creates a real confidentiality risk because user-supplied text can be intercepted or modified by a local network attacker, proxy, or compromised host service, especially since the question may contain sensitive work details.
The script stores the user's free-form question in order records without any visible notice, minimization, or consent step. Because prompts may contain personal, proprietary, or sensitive business information, silent persistence increases privacy and data-retention risk if local storage is later accessed, exfiltrated, or reused beyond the user's expectations.
This Java code contains multiple fixed Chinese-language response messages and generated content, starting with the error text at L038-L039 and continuing throughout the controller. The file provides no indication that users can opt into Chinese or select another locale, which violates the language/locale policy criterion for natural-language content.
The answer is generated from the question value supplied in the getResult request instead of the question originally stored with the order. This lets a user pay once, then submit different prompts at retrieval time, bypassing the intended binding between payment and purchased content.
The response generator returns Chinese-language defaults, feedback text, reply text, internal monologue, and verdict strings regardless of the user's language preference. Because the file does not offer any locale selection or document a justified region-specific restriction, this is a natural-language policy violation.
The file's natural-language framing and responses are entirely Chinese and present the service as Chinese-language only, with no indication that users may choose another language or locale. This can violate the language/locale policy when a specific language is imposed without explicit opt-in or documented justification.
This code processes a user-supplied payment credential by decrypting it and interpreting payment status, but the file provides no user-facing disclosure, confirmation, or explanatory comment that sensitive payment data will be handled. For code files, handling sensitive credentials without any visible warning can qualify as missing user disclosure when the behavior is not surfaced to the user.
The inline 'simulation mode' behavior documents an intentional fallback that treats verification failure as payment success, which normalizes insecure behavior in production code. In the context of a paid service claiming mandatory payment verification, this materially increases the risk of unauthorized access and revenue loss.
The module docstring and CLI description present the script as simply generating absurd client feedback locally. In practice, the main behavior first performs order/payment-dependent backend retrieval, so the documentation omits and softens the payment-gated nature of the operation described by the manifest and implemented in code.
The module docstring specifies the skill in Chinese and the program's user-facing strings are entirely Chinese, indicating a fixed language behavior. The file does not offer user language selection or explain that the skill is intentionally limited to a Chinese-speaking audience.
The raised RuntimeError contains a Chinese-only message, which imposes a specific language on users without any opt-in or fallback. This is a natural-language policy concern because the file gives no indication that the skill is intentionally limited to Chinese-speaking users.
The function creates directories and writes JSON order data to disk, which changes persistent user data. In this file there is no confirmation prompt, logging, print statement, or explanatory comment/docstring disclosing that the operation will create or overwrite files.
No suspicious patterns detected.