Back to skill

Security audit

TingDong Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-aligned, but it sends user text or links to a remote podcast service over unencrypted HTTP with weak privacy and scraping safeguards.

Review before installing. Do not submit private, confidential, internal, paywalled, or sensitive copyrighted material unless you are comfortable sending it to the listed remote service over unencrypted HTTP. Also consider whether fetching a target site with Playwright complies with that site's terms and access rules.

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/generate_podcast.py:16
Finding

Podcast content and API responses transmitted over unauthenticated plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_podcast.py, lines 16–40
Vulnerability Type: Cleartext transmission of user content and service responses
Risk Level: Medium

Vulnerable Code

python
BASE_URL = "http://111.229.22.145:8092"
API_PREFIX = "/api/v1"


def call_api(endpoint: str, payload: dict = None, method: str = "GET", timeout: int = 30) -> dict:
    """调用后端 API"""
    url = f"{BASE_URL}{API_PREFIX}{endpoint}"
    
    if method == "POST" and payload:
        data = json.dumps(payload).encode("utf-8")
        headers = {"Content-Type": "application/json"}
        req = urllib.request.Request(url, data=data, headers=headers, method="POST")
    else:
        req = urllib.request.Request(url, method=method)
    
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        error_body = e.read().decode("utf-8")

Technical Analysis

The client hardcodes a backend URL using plaintext HTTP and sends podcast-generation requests through urllib.request.urlopen. The request payload assembled by submit_task contains the complete user-supplied article text or URL, content type, style, duration, and user identifier.

HTTP provides neither transport confidentiality nor authenticated server identity. A network-positioned attacker can therefore inspect the submitted content and modify requests or responses in transit. Polling requests and their responses are also sent over HTTP, exposing task identifiers, processing results, generated titles, source metadata, and audio URLs.

Because the client directly parses and trusts the returned JSON, an active interceptor can forge a successful result containing altered metadata or an attacker-selected audio URL. The reviewed code does not execute the response as code, so this finding does not establish arbitrary ...[truncated 1242 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the plaintext endpoint with an HTTPS URL backed by a valid, trusted certificate.
  2. Do not implement an automatic fallback from HTTPS to HTTP.
  3. Retain Python’s default certificate and hostname verification, and fail closed on TLS validation errors.
  4. Consider application-level response authentication or signed, short-lived result URLs if response integrity is security-sensitive.
  5. Clearly disclose that article text and URLs are transmitted to an external backend before submission, especially when users may provide confidential material.
  6. Minimize transmitted metadata and avoid persistent or identifying user_id values unless required by the service.
  7. Validate returned URLs before presenting them, including requiring HTTPS and restricting them to documented trusted origins where appropriate.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 (9)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The backend base URL uses plain HTTP, so submitted text, URLs, task identifiers, and returned audio links can be intercepted or modified by any network attacker on the path. Because this skill is specifically designed to transmit user content to a remote service, lack of transport security materially increases both privacy exposure and integrity risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill clearly describes network-capable behavior such as fetching arbitrary URLs, using Playwright for web access, and calling backend APIs, but it does not declare any corresponding tool scope or permissions. This creates a transparency and governance gap: users and host platforms cannot easily assess or constrain outbound network use, increasing the risk of unintended data transmission or misuse of fetch capabilities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the system to send user-provided text or URLs to backend services for content fetching and podcast/audio generation, but it does not warn the user that their supplied content will be transmitted to external systems. This can expose sensitive article contents, private links, or pasted confidential text without informed consent, especially because the workflow encourages direct pasting of arbitrary material.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The API documentation explicitly invites users to submit article URLs or raw text and later exposes generated audio via a public HTTP URL, while also stating that audio is retained for 7 days. Without any privacy notice, consent language, or data-handling guidance, users may unknowingly send third-party or sensitive content to a backend that stores and processes it, creating privacy, compliance, and unauthorized disclosure risk. The use of plain HTTP in the documented base URL and audio URL further increases exposure in transit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill documentation explicitly recommends using Playwright to '绕过反爬' and tuning User-Agent/delays to evade anti-scraping controls on third-party platforms. That encourages behavior that can violate site terms, trigger account or IP blocking, and create legal/compliance exposure for users or operators, especially because the surrounding guidance frames the risk as relatively low and does not require authorization checks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script submits arbitrary user-provided article text or URLs to a remote backend, but there is no explicit consent prompt, privacy notice, or indication in the CLI output that the content leaves the local environment. In this skill context, users may paste private articles, internal URLs, or sensitive text, so silent exfiltration to an external service creates a real confidentiality risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The example configuration hard-codes zh-CN-XiaoxiaoNeural, which imposes a specific locale by default. Although line L107 mentions the voice parameter can be changed, the skill description does not present language/locale selection as an explicit user choice or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The entire document, including headings, parameter descriptions, progress messages, and notes, is presented exclusively in Chinese. Per the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file's user-facing descriptive strings and comments prominently use Chinese, which may impose a locale expectation without opt-in. Under the policy, forcing a specific language can be a natural-language policy issue unless the tool offers language choice or clearly documents that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.