Back to skill

Security audit

Ecommerce Ad Copy Generator Free

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed freemium ad-copy generator with a narrow payment-link helper and no hidden persistence, network execution, or data exfiltration found.

Before installing, be aware that the free generator outputs Chinese ad copy and includes a returned premium upgrade payment link. Use only trusted payment URL configuration, and avoid passing untrusted or special-character user_id values until the link construction is hardened.

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

T09 · Insecure Skill Coding Practices

Note
Location
scripts/ecommerce_ad_copy_generator_free.py:25
Finding
User-Controlled Identifier Is Inserted into Payment URL Without Encoding## Vulnerability Details **File Location**: `scripts/ecommerce_ad_copy_generator_free.py`, lines 25-30 **Vulnerability Type**: Improper encoding of a user-controlled URL query parameter **Risk Level**: Low ```python def _payment_url(user_id: str) -> str: template = os.getenv("SKILLPAY_PAYMENT_URL_TEMPLATE", "").strip() if template: return template.format(user_id=user_id) base = os.getenv("SKILLPAY_TOPUP_BASE_URL", "https://skillpay.me/pay").strip() sep = "&" if "?" in base else "?" return f"{base}{sep}user_id={user_id}" ``` ### Technical Analysis The `_payment_url` function inserts the user-controlled `user_id` directly into a URL template or query string. The input validation elsewhere in the application only requires `user_id` to be nonempty; it does not impose a safe identifier grammar, length limit, or URL encoding. Consequently, reserved URL characters such as an ampersand, number sign, equals sign, or question mark can change the structure or interpretation of the generated payment URL. In the fallback path, an attacker can inject additional query parameters. The configured template path has the same underlying weakness because `str.format` performs no contextual URL encoding. This is a URL construction vulnerability rather than server-side request forgery: the audited code returns the generated URL in JSON but does not make a network request itself. ### Attack Path 1. An attacker supplies a crafted `user_id`, for example through the `--user-id` command-line argument or an input JSON payload. 2. The value passes validation because it is nonempty. 3. `run()` passes the identifier to `_payment_url()`. 4. `_payment_url()` interpolates it without percent-encoding. 5. A value such as `victim&redirect=https://example.invalid` produces a URL containing an injected `redirect` query parameter. 6. The modified URL is returned in the `upgrade.payment_url` field. 7. If a cons ...[truncated 785 chars]
Remediation
## Remediation Suggestions 1. Validate `user_id` against an explicit allowlist appropriate for the identifier format, such as ASCII letters, digits, underscores, and hyphens, and enforce a reasonable maximum length. 2. Build query strings with `urllib.parse.urlencode` rather than direct string concatenation. 3. Parse and reconstruct configured base URLs with `urllib.parse.urlsplit`, `parse_qsl`, and `urlunsplit` so existing query parameters are preserved safely. 4. Avoid applying `str.format` directly to a URL template with unencoded user input. Percent-encode the identifier before substitution, or replace URL templates with structured URL construction. 5. Validate configured payment URLs to permit only expected HTTPS origins if deployment configuration is not fully trusted. 6. Add tests covering ampersands, number signs, equals signs, question marks, Unicode input, duplicate parameters, and base URLs that already contain query strings.
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill advertises executable behavior and static analysis detected capabilities involving environment access and file reading, but the manifest does not declare any tool scope such as permissions or allowed-tools. This creates a transparency and least-privilege problem: reviewers and users cannot tell what resources the skill may access, increasing the risk of unintended data exposure or overbroad execution in hosts that honor manifest-declared restrictions.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The example invocation uses Chinese selling points and target audience, while the skill description does not state that the skill is China-specific or that language is user-selectable. This creates a natural-language locale policy concern because the skill appears to assume a specific language context without explicit opt-in or justification.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The manifest describes a free basic ad copy generator that produces 3 copies and reserves premium upgrade hooks. While premium hooks are in scope, the code goes beyond merely reserving them by constructing a live payment URL from environment configuration and returning it in responses. That introduces monetization/payment behavior not described as part of the skill's actual operation.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
An ecommerce ad copy generator would be expected to validate inputs and generate copy text, but reading payment URL templates and top-up base URLs from environment variables is not necessary for that core purpose. This capability is only justified if the manifest explicitly states payment-link generation or billing integration, which it does not.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The generated ad copy strings are all hard-coded in Chinese, and the script provides no option for the user to choose language or locale. This creates a natural-language policy issue because it forces a specific language on all users without opt-in or justification.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This code includes natural-language strings in Chinese for selling points and target audience, which suggests the skill may be oriented to a specific language/locale. Under the policy, forcing a specific language without user opt-in or clear justification is a natural-language policy concern.

Static analysis

No suspicious patterns detected.