Back to skill

Security audit

Ticket Signal Watch

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed ticket-page monitoring helper, but users should keep its target URLs trusted and public-facing.

Install only if you are comfortable with a skill that fetches configured ticket pages and writes a local state file. Keep the target config under trusted control, use official public ticket pages where possible, avoid internal/private-network URLs, and review any webhook forwarding before sending alert output externally.

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/watch_ticket_pages.py:66
Finding

Unrestricted Target URLs Enable Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/watch_ticket_pages.py, lines 66-73 and 136-140
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: Medium

Vulnerable Code

python
def fetch_url(url: str, user_agent: str, timeout_seconds: int) -> dict[str, Any]:
    req = Request(
        url,
        headers={
            "User-Agent": user_agent or DEFAULT_USER_AGENT,
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        },
    )
    started_at = time.time()
    try:
        with urlopen(req, timeout=timeout_seconds) as resp:
            body = resp.read()

The URL originates directly from configuration:

python
targets.append(
    Target(
        name=raw["name"],
        platform=raw["platform"],
        url=raw["url"],
        require_all=normalize_keywords(raw.get("require_all")),
        match_any=normalize_keywords(raw.get("match_any")),
        signal_high=normalize_keywords(signal_keywords.get("high")),
        signal_medium=normalize_keywords(signal_keywords.get("medium")),
        note=raw.get("note"),
    )
)

Technical Analysis

A configuration-controlled target URL is passed directly to urllib.request.Request and urlopen. Validation is limited to checking whether the URL field is non-empty; the code does not restrict URL schemes, destination hosts, ports, resolved IP ranges, or redirect destinations.

An attacker who can create or modify the target configuration can cause the process to issue requests from its own network environment to destinations such as:

  • Loopback services
  • Private-network services
  • Link-local or cloud metadata endpoints
  • Services reachable only from the host running the skill
  • Internal destinations reached through redirects

The application exposes request status and up to the configured preview_chars of response-derived text in its structured output. This output may subsequently be forwarded to a channel, webhook, file, or queue as recommended by the s ...[truncated 1824 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict URL schemes

    • Parse every target with urllib.parse.urlsplit.
    • Permit only explicitly required schemes, preferably https.
    • Reject file, ftp, data, and all other non-HTTP schemes.
    • Reject URLs containing embedded credentials.
  2. Apply a destination allowlist

    • Prefer an explicit allowlist of supported official ticket-platform domains.
    • Compare normalized hostnames exactly or against carefully implemented subdomain rules.
    • Do not use unsafe suffix checks such as hostname.endswith("example.com") without requiring a label boundary.
  3. Block non-public network destinations

    • Resolve all destination hostnames before connecting.
    • Reject every resolved IPv4 and IPv6 address that is loopback, private, link-local, multicast, reserved, unspecified, or otherwise non-global.
    • Protect against alternate IP representations and IPv4-mapped IPv6 addresses.
    • Consider DNS rebinding defenses by connecting only to validated resolved addresses while preserving correct TLS hostname verification.
  4. Control redirects

    • Disable automatic redirects or implement a restricted redirect handler.
    • Validate the scheme, hostname, port, and resolved addresses of every redirect destination.
    • Set a low maximum redirect count.
  5. Constrain ports and responses

    • Allow only expected ports, normally 443 and optionally 80.
    • Limit response size before reading the complete body to reduce denial-of-service exposure.
    • Avoid returning response previews by default, especially for failed or non-allowlisted destinations.
  6. Harden configuration trust

    • Treat target configuration as privileged input.
    • Restrict write access to configuration files.
    • Validate every target at load time and fail closed with an explicit error rather than silently accepting unsafe destinations.
  7. Add security tests

    • Test rejection of loopback, RFC 1918, link-local, IPv6 local, m ...[truncated 91 chars]
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises a script that reads configuration, writes state, and performs network fetching, but the manifest does not declare any explicit tool scope or permissions boundaries. That creates a least-privilege and review gap: a host system or operator may enable the skill without understanding that it can access files and remote resources, increasing the chance of unintended data access, SSRF-like fetching, or unsafe file writes depending on runtime controls.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation presents Chinese trigger phrases as the examples of strong signals to use, but does not offer a language choice or explain that the skill is limited to Chinese-language ticket pages. This creates a natural-language locale constraint that may not fit all users or targets and is not clearly documented as an opt-in regional specialization.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The request header hard-codes a locale preference of zh-CN/zh ahead of English, which imposes a specific language/locale choice on all users. This matches the natural-language policy concern for locale forcing because the file does not offer a user choice or explain a region-specific need.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The config hard-codes Chinese platform and search/match keywords such as "大麦", "周杰伦", and ticket-status phrases, which constrains the skill to a specific language/locale. Under the policy, locale-specific behavior should either be clearly justified as region-specific or offer user opt-in/choice; this example config does neither.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code performs HTTP requests to target URLs and later persists fetched-page state to disk, but the script provides no visible user-facing notice about these actions beyond neutral CLI argument descriptions. Under the code-file criteria, network calls and file writes should have some disclosure such as an explanatory comment, docstring, or explicit user-facing message unless clearly covered elsewhere.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.