Back to skill

Security audit

E-commerce Data Analyzer

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (7)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app.py:39
Finding

Forgeable Flask Sessions Permit Payment Verification Bypass

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app.py:48
Finding

SkillPay API Credential Is Embedded in Documentation, Application Code, and Tests

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/app.py:123
Finding

Analysis and PDF Endpoints Lack File Ownership and Payment Authorization Checks

Content
View full analysis
') def analysis(filename): filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) df = pd.read_csv(filepath) df['订单日期'] = pd.to_datetime(df['订单日期']) ``` ```python @app.route('/generate_pdf/', methods=['POST']) def generate_pdf(filename): cost_data = request.form.to_dict() filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) df = pd.read_csv(filepath) ``` By contrast, the upload handler records a filename in the session: ```python file.save(filepath) session['data_file'] = filename return redirect(url_for('analysis', filename=filename)) ``` Neither downstream endpoint verifies that the requested filename equals the file recorded for the current session. ### Technical Analysis The filename in both routes is an attacker-controlled object identifier. The application does not require authentication, verify payment state, check `session['data_file']`, or maintain a server-side ownership relationship between a user and an uploaded file. Uploaded files receive UUID names, which reduces casual guessing but is not an authorization control. UUIDs can be exposed through browser history, logs, referrer information, screenshots, copied links, or other operational channels. A user who learns another upload's identifier can access its rendered analysis directly. The PDF endpoint also processes any referenced upload without independently checking payment or ownership. The code additionally lacks canonical-path validation. The default Flask string route converter normally does not accept literal slashes, which limits straightforward traversal through these routes, but path safety should still be enforced independently of routing behavior. ### ...[truncated 991 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app.py:328
Finding

Development Debugger Is Exposed on All Network Interfaces

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/app.py:115
Finding

Unbounded CSV Processing and Persistent Artifact Storage Enable Resource Exhaustion

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/app.py:96
Finding

State-Changing Billing and Report Requests Lack CSRF Protection

Content
View full analysis

📤 上传并分析 ``` ```html {% for name in product_rank.keys() %}
{{ name }} 单位成本(USD):
{% endfor %} 生成并下载PDF报告 ``` The corresponding endpoints do not validate a CSRF token: ```python @app.route('/upload', methods=['POST']) def upload_file(): user_id = session.get('user_id', str(uuid.uuid4())) session['user_id'] = user_id if not TEST_MODE and not session.get('payment_verified'): charge_result = charge_user(user_id) ``` ```python @app.route('/generate_pdf/', methods=['POST']) def generate_pdf(filename): cost_data = request.form.to_dict() ``` ### Technical Analysis Both state-changing forms omit anti-CSRF tokens. The upload handler performs its payment or charge operation before verifying that a file was supplied: ```python if not TEST_MODE and not session.get('payment_verified'): charge_result = charge_user(user_id) ... session['payment_verified'] = True if 'file' not in request.files: return '没有选择文件', 400 ``` Consequently, a POST request without a file can reach the billing action before being rejected. Browser cookie behavior may reduce exploitability in some modern configurations, but the application does not explicitly c ...[truncated 1076 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:40
Finding

Runtime Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

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.

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 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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

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.

Content

Scanner excerpt · scripts/app.py (reported line 64)May include surrounding context.

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

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.

Content

Scanner excerpt · scripts/app.py (reported line 88)May include surrounding context.

python
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")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

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.

Content

Scanner excerpt · test_payment.py (reported line 42)May include surrounding context.

python
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}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

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.

Content

Scanner excerpt · test_payment.py (reported line 84)May include surrounding context.

python
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}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
98% confidence
Finding

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.

Content

Scanner excerpt · test_skillpay.py (reported line 29)May include surrounding context.

python
return {"ok": True, "balance": 1000}
    
    try:
        resp = requests.post(
            f"{BILLING_URL}/charge", 
            headers=HEADERS, 
            json={

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

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.

Content

Scanner excerpt · test_skillpay.py (reported line 99)May include surrounding context.

python
return "https://example.com/payment"
    
    try:
        resp = requests.post(
            f"{BILLING_URL}/payment-link", 
            headers=HEADERS, 
            json={

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.