T09 · Insecure Skill Coding Practices
- Location
scripts/app.py:39- Finding
Forgeable Flask Sessions Permit Payment Verification Bypass
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a real ecommerce CSV analytics app, but it ships payment credentials and runs an unsafe web service configuration that users should review before installing.
Install only in an isolated local environment after removing and rotating the embedded SkillPay key, replacing the Flask secret, disabling debug mode, binding to localhost, adding authorization checks, and defining retention/deletion controls for uploaded CSVs and generated reports.
scripts/app.py:39Forgeable Flask Sessions Permit Payment Verification Bypass
scripts/app.py:48SkillPay API Credential Is Embedded in Documentation, Application Code, and Tests
scripts/app.py:123Analysis and PDF Endpoints Lack File Ownership and Payment Authorization Checks
scripts/app.py:328Development Debugger Is Exposed on All Network Interfaces
scripts/app.py:115Unbounded CSV Processing and Persistent Artifact Storage Enable Resource Exhaustion
scripts/app.py:96State-Changing Billing and Report Requests Lack CSRF Protection
SKILL.md:40Runtime Dependencies Are Installed Without Version or Integrity Pinning
If the actual behavior lacks the promised analytics features and instead focuses on billing API interaction with a hardcoded key, the skill is materially misrepresented. Such misrepresentation can be used to obtain trust, trigger network calls, or test payment infrastructure under the guise of ordinary business tooling, which is especially risky in a financial integration context.
If the actual behavior lacks the promised analytics features and instead focuses on billing API interaction with a hardcoded key, the skill is materially misrepresented. Such misrepresentation can be used to obtain trust, trigger network calls, or test payment infrastructure under the guise of ordinary business tooling, which is especially risky in a financial integration context.
If the actual behavior lacks the promised analytics features and instead focuses on billing API interaction with a hardcoded key, the skill is materially misrepresented. Such misrepresentation can be used to obtain trust, trigger network calls, or test payment infrastructure under the guise of ordinary business tooling, which is especially risky in a financial integration context.
The documentation exposes what appears to be a live SkillPay API key directly in the skill file. Hardcoded secrets are highly dangerous because anyone with access to the repository or package can reuse the credential to create charges, access billing functions, abuse the account, or pivot into broader compromise of financial systems.
The skill declares no explicit tool scope or permissions, yet the documentation indicates external network use via SkillPay. This creates an authorization and transparency gap: users and hosting platforms cannot clearly constrain or review outbound actions, especially when money-related API calls are involved. In the context of a data-analysis skill, undeclared network capability is more dangerous because users may expect purely local processing.
The skill accepts uploaded CSV sales data and generates PDF output, but the documentation does not explain how uploaded business data is stored, processed, retained, or written to disk. This is risky because sales data may contain sensitive commercial information, and users are not informed about local file writes, report persistence, or possible data exposure through generated artifacts.
The phrase '全中文界面支持' indicates the skill is limited to a Chinese-language interface, and the document does not offer any language choice or explain a justified region-specific constraint. This matches the policy category for language or locale restrictions without user opt-in.
Comments, UI strings, report labels, and font setup all indicate the application is designed around Chinese-language output, but there is no visible opt-in or language-selection path in this file. The policy for natural-language violations applies to forced language or locale behavior when users are not given a choice.
This request includes a hardcoded API key in HEADERS used to authenticate to an external billing service. Hardcoded secrets in application code are dangerous because anyone with code access, repository access, logs, or a leaked package can abuse the billing API, potentially charging users fraudulently or querying billing state. In this ecommerce skill context, compromise directly affects payments, making the issue more sensitive than a generic outbound request.
if TEST_MODE:
return {"ok": True, "balance": 1000}
try:
resp = requests.post(f"{BILLING_URL}/charge", headers=HEADERS, json={
"user_id": user_id, "skill_id": SKILL_ID, "amount": 0,
}, timeout=10)
data = resp.json()
The charge request sends a user_id and skill metadata to an external billing service over HTTP. The code has error logging, but there is no user-facing disclosure, confirmation, or nearby documentation explaining that user/session data is sent to a third-party billing endpoint.
This external payment-link request relies on the same hardcoded billing API key, exposing privileged payment functionality if the code is leaked. An attacker with the key could create payment links or interact with the billing backend outside intended controls, which is especially risky in a payment-enabled ecommerce analysis skill.
if TEST_MODE:
return url_for('index', _external=True) + '?test_payment=success'
try:
resp = requests.post(f"{BILLING_URL}/payment-link", headers=HEADERS, json={
"user_id": user_id, "amount": 8,
}, timeout=10)
return resp.json().get("payment_url")
The payment flow posts the user's generated identifier and payment amount to an external API to obtain a payment URL. This is a network transmission of user-related data, but the code does not include a user-facing disclosure or explanatory comment describing the external data sharing.
The page declares lang="zh-CN" and the visible interface text is entirely Chinese, including an explicit feature claim of a full Chinese-only interface. Under SQP-3, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is justified or alternatives are offered.
This HTML file is a code file, so SQP-2 applies to safety-relevant behaviors exposed by the interface. The form invites users to upload detailed sales, revenue, channel, and inventory data, but there is no disclosure about how the data will be processed, stored, or protected, despite the obvious sensitivity of commercial data.
The HTML document declares lang="zh-CN", and all visible UI text is presented only in Simplified Chinese. For a general-purpose payment-required page, this imposes a specific language/locale without any opt-in or explanation that the skill is limited to a Chinese-speaking region.
The file's comments, docstrings, and printed user-facing messages are consistently in Chinese, which imposes a specific language on users without any opt-in or fallback. Under the policy, locale or language constraints should either be optional or clearly justified as region-specific.
The code transmits payment data to an external service using a hardcoded SkillPay API key embedded directly in the source. Even though the key is masked in logs, it is still sent over the network and exposed to anyone with source access, enabling unauthorized order creation or API abuse if the repository or skill package is shared.
print(f"请求参数: api_key=***, order_id={order_id}, amount=0.001, currency=USDT")
try:
response = requests.post(SKILLPAY_CREATE_ORDER_URL, json=payload, timeout=10)
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
This request sends order verification data to an external payment endpoint using the same hardcoded API credential. In the context of an ecommerce analytics skill with payment integration, embedding a live payment secret in a test file is particularly dangerous because it can allow third parties to query or manipulate payment workflows and may expose sensitive transactional metadata.
print(f"请求参数: api_key=***, order_id={order_id}")
try:
response = requests.post(SKILLPAY_VERIFY_ORDER_URL, json=payload, timeout=10)
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
The file contains a hardcoded live-looking SkillPay API key that is sent in headers during external requests. Embedding secrets directly in source code is dangerous because anyone with repository or package access can reuse the credential to query billing APIs, create charges, or generate payment links, potentially causing account abuse and financial impact.
return {"ok": True, "balance": 1000}
try:
resp = requests.post(
f"{BILLING_URL}/charge",
headers=HEADERS,
json={
This code sends a generated user ID, skill ID, and charge amount to an external billing endpoint. Although it prints response details, it does not clearly disclose before transmission that user-related billing data will be sent to a remote service, and there is no confirmation prompt or warning comment near the network action.
The balance-check function performs a GET request to a remote billing API with a user_id parameter. The function logs status and results, but it does not warn the user beforehand that identifier data will be transmitted to an external billing system.
This external transmission uses the same hardcoded API credential to call the payment-link endpoint, extending the blast radius of the exposed secret. An attacker who obtains the source can invoke provider APIs under the skill owner's account, which is especially concerning in an ecommerce/payment context where misuse can lead to fraudulent payment flows or billing abuse.
return "https://example.com/payment"
try:
resp = requests.post(
f"{BILLING_URL}/payment-link",
headers=HEADERS,
json={
This function posts user_id and amount to a remote payment-link endpoint. While the code prints the returned URL, it lacks a clear warning or confirmation that payment-related user data is being transmitted off-system.
The upload handler saves the submitted CSV to the server filesystem, which is a file-write operation covered by the missing-warning rule for code files. While this is functionally expected for an upload workflow, this file does not include a confirmation prompt, user-facing notice, or explanatory comment/docstring near the write.
The report generation flow creates a PDF under the reports directory before returning it to the user, which is another file-write operation. This file does not provide a visible warning, prompt, or explanatory comment indicating that a server-side copy of the report is created.
No suspicious patterns detected.