Back to skill

Security audit

MusicRouter

Security checks for vulnerabilities and agentic risk

Overview

This music-link converter is coherent overall, but its URL handling can make requests to unintended internal or arbitrary hosts.

Review before installing if this skill will run in an agent, server, or shared environment that can access private networks or sensitive local services. It should validate URLs by scheme and hostname, block private/link-local/loopback destinations, and revalidate redirects. For personal use, also expect submitted music links and derived metadata to be sent to song.link and music-platform APIs; avoid enabling --log on shared systems unless you are comfortable retaining that history locally.

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

Error
Location
scripts/converter.py:64
Finding
Server-Side Request Forgery Through Inadequate Music URL Validation## Vulnerability Details **File Location**: `scripts/converter.py`, lines 64–67 and 77 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```python def identify_platform(self, url): self.logger.debug(f"Identifying platform for URL: {url}") for platform_id, info in self.platforms.items(): for pattern in info["patterns"]: if re.search(pattern, url): self.logger.info(f"Identified platform: {platform_id}") return platform_id ``` The accepted URL is subsequently requested with redirects enabled: ```python response = requests.get( url, headers=headers, timeout=10, allow_redirects=True ) ``` ### Technical Analysis The application determines whether a URL belongs to a supported music platform by searching the entire unparsed URL for an approved-domain pattern. It does not parse the URL and verify that the hostname exactly matches an approved domain or one of its legitimate subdomains. Consequently, an attacker can place an approved domain string in another URL component, such as the query string, path, or user-information section, while directing the actual request to an attacker-selected host. For example: ```text http://169.254.169.254/latest/meta-data/?music.163.com ``` The string `music.163.com` satisfies the regular-expression check, causing the URL to be classified as a NetEase link. `get_song_info()` then sends an HTTP GET request to the link-local metadata address. Redirect processing creates a second exploitation route. Because `allow_redirects=True` is set and redirect destinations are not revalidated, a URL initially hosted on an accepted or attacker-controlled public endpoint can redirect the request to a loopback, private-network, or link-local address. The ten-second timeout limits request duration but does not prevent access to internal resources. ### Attack Path 1. An attacker supplies a URL that contains a supported ...[truncated 1670 chars]
Remediation
## Remediation Suggestions 1. Parse each supplied URL with `urllib.parse.urlsplit()` and reject malformed URLs, credentials in URLs, unexpected ports, and all schemes except `https`. 2. Compare the normalized hostname against an explicit allowlist. Accept only exact approved hosts or intentional subdomains using boundary-safe checks such as: ```python hostname == allowed_domain or hostname.endswith("." + allowed_domain) ``` 3. Resolve the hostname before connecting. Reject every resolved IPv4 and IPv6 address that is loopback, private, link-local, multicast, reserved, or unspecified, using Python's `ipaddress` module. 4. Disable automatic redirects with `allow_redirects=False`. If redirects are required, process them individually, parse and validate every destination, enforce a low redirect limit, and repeat DNS/IP checks before each request. 5. Mitigate DNS rebinding by ensuring the address validated is the address used for the connection. Where possible, enforce outbound restrictions at the network or proxy layer. 6. Permit outbound traffic only to documented music-platform hosts and API endpoints through firewall or egress-proxy rules. 7. Limit response sizes and accepted content types before parsing response bodies. 8. Add automated tests covering approved hosts, deceptive suffixes, user-information tricks, approved strings in paths and queries, encoded hostnames, redirects to internal addresses, IPv4 variants, and IPv6 loopback or link-local targets.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill explicitly states it uses the Odesli/song.link API and fetches album artwork, which implies user-supplied music links and related metadata are transmitted to a third party. Because the documentation does not clearly warn about this external data sharing, users and agents may unknowingly disclose listening preferences or other potentially sensitive input-derived data to an outside service.

External Transmission

Medium
Category
Data Exfiltration
Content
def get_songlink_data(self, url):
        """使用 Odesli (song.link) API 获取并解析所有平台链接及封面图"""
        self.logger.debug(f"Fetching song.link data for URL: {url}")
        api_url = f"https://api.song.link/v1-alpha.1/links?url={urllib.parse.quote(url)}"
        try:
            response = requests.get(api_url, timeout=10)
            if response.status_code == 200:
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The skill documents an optional logging feature that records conversion details to a local file, but it does not adequately warn that user inputs and resolved links may be persisted on disk. This can create unintended retention of potentially sensitive music links, metadata, or usage history, especially on shared systems or in agent environments where logs are centrally collected.

Static analysis

No suspicious patterns detected.