Back to skill

Security audit

YouTube Video To Blog Converter

Security checks for vulnerabilities and agentic risk

Overview

The converter itself is simple, but it bundles and emits under-disclosed payment and billing behavior that users should review before installing.

Review this skill before installing if you do not want payment prompts or billing-related artifacts in a transcript converter. It should not be allowed to initiate charges automatically, and any payment URL configuration should be restricted to trusted HTTPS hosts with encoded parameters. Users who need non-Chinese output should also confirm language support first.

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

Warning
Location
scripts/youtube_video_to_blog_converter.py:14
Finding

Unvalidated and Unencoded Payment URL Construction

Content
View full analysis
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}" ``` The generated value is exposed in the response: ```python upgrade = { "premium_available": True, "price_usdt": "0.10", "payment_url": _payment_url(validated["user_id"]), "premium_features": ["SEO标题与摘要优化", "自动配图建议", "多平台发布格式(公众号/Medium)"], } ``` ### Technical Analysis The application directly interpolates the user-controlled `user_id` into a URL without percent-encoding it. Reserved URL characters such as `&`, `=`, `#`, and `?` can therefore alter the structure or interpretation of the generated payment URL. For example, a `user_id` containing `victim&amount=100` produces a URL resembling: ```text https://skillpay.me/pay?user_id=victim&amount=100 ``` The payment service may interpret the injected text as a separate query parameter rather than as part of the identifier. Whether a particular parameter changes billing behavior depends on the downstream service, but the generated URL no longer reliably represents the validated input. The configurable base URL and template are also accepted without scheme or hostname validation. If deployment configuration is compromised or incorrectly supplied, the returned link could use plaintext HTTP, an unexpected external host, or a non-web scheme. Template substitution does not encode `user_id`, so the same injection weakness exists in both configuration paths. This issue ...[truncated 2234 chars]
Remediation
View remediation
str: parsed = urlsplit(base) query = dict(parse_qsl(parsed.query, keep_blank_values=True)) query["user_id"] = user_id return urlunsplit( (parsed.scheme, parsed.netloc, parsed.path, urlencode(query), parsed.fragment) ) ``` 2. Parse and validate configured URLs before returning them: - Require the exact `https` scheme. - Require a nonempty hostname. - Use an explicit allowlist of approved payment hostnames. - Reject embedded credentials, control characters, and unexpected ports. - Avoid substring or suffix-only hostname checks that can be bypassed by lookalike domains. 3. Restrict `user_id` to the application's expected identifier format, such as a conservative length-bounded allowlist: ```python if not re.fullmatch(r"[A-Za-z0-9_-]{1,64}", user_id): raise ValidationError("`user_id` has an invalid format") ``` This input restriction should supplement, not replace, proper URL encoding. 4. Avoid arbitrary format templates where possible. Prefer a validated base URL and append parameters programmatically. If template support is required, validate the fully rendered URL after substitution and ensure the identifier is percent-encoded before insertion. 5. Add tests covering: - Identifiers containing `&`, `=`, `?`, `#`, whitespace, and Unicode. - HTTP and non-web schemes. - Unexpected or deceptive hostnames. - Existing query parameters. - Configured templates and base URLs. - Rejection of control characters and malformed URLs. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares executable behavior and detected capabilities involving environment access and file reading, but the manifest does not define any explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an agent or reviewer cannot clearly constrain what the skill is permitted to access, increasing the chance of over-broad execution or unintended data exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The title and described output are explicitly framed as a Chinese-language YouTube-video-to-blog converter, and the example content is also Chinese. There is no indication that users may choose another language or that the locale restriction is required for a region-specific purpose, which conflicts with the policy against forcing a language without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document defines a live billing charge operation and payment fallback flow but does not clearly warn that calling the endpoint may debit a user's account or trigger a payment/top-up process. In an agent skill context, this omission is risky because downstream developers or automated components may treat the contract as routine API usage and invoke billing behavior without explicit user awareness or consent safeguards.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill reads deployment environment variables to build a payment or upgrade URL even though its advertised purpose is transcript-to-blog conversion. This creates an unnecessary trust boundary crossing: a compromised or misconfigured environment can inject arbitrary external destinations into user-facing output, enabling phishing, unwanted monetization redirects, or data exfiltration via crafted links.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The generated blog draft uses fixed Chinese section headings and fallback text, which forces a specific language regardless of the user's input or preferences. This is a natural-language policy issue because the file does not provide opt-in, language selection, or justification for the locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
70% confidence
Finding

The command-line description presents a general-purpose converter, but elsewhere the implementation always emits Chinese headings and default copy. Because the locale behavior is not disclosed or selectable, users may reasonably expect language-neutral behavior and receive forced Chinese output instead.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.