Back to skill

Security audit

Music Search

Security checks for vulnerabilities and agentic risk

Overview

The skill broadly matches music-resource search, but its file-reading, URL-fetching, and runtime dependency installation behaviors need careful review before installation.

Install only if you are comfortable with a skill that performs live third-party crawling, can install Python packages at runtime, caches results locally, and currently has unsafe @file and URL-fetching behavior. Do not pass untrusted arguments to it, avoid using it in environments with sensitive local files or internal network access, and prefer a revised version that removes @file expansion, validates URLs, pins dependencies, and parses .env safely.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (6)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/music-search.sh:39
Finding
Arbitrary Local File Disclosure Through Bash Argument Expansion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/music-search.sh:39-48` **Vulnerability Type**: Unrestricted local file read followed by external transmission **Risk Level**: High ### Vulnerable Code ```bash args=() if [ $# -gt 0 ]; then args=("$@") for i in "${!args[@]}"; do if [[ "${args[$i]}" == @* ]]; then filepath="${args[$i]:1}" if [ -f "$filepath" ]; then args[$i]="$(cat "$filepath")" fi fi done fi ``` ### Technical Analysis Every command-line argument beginning with `@` is interpreted as a local file path. There is no path allowlist, canonical-path validation, ownership check, or restriction to files created by the skill. The complete contents of a readable file replace the original argument. If this argument occupies the search keyword position, `music-search.js` incorporates the contents into queries passed to the external `web-search` skill. If that discovery mechanism fails, the query can also be submitted to Baidu through `deep_extract.py`. This crosses a least-privilege boundary because a music-search command does not legitimately require unrestricted access to arbitrary local files. The `@file` behavior is also not documented as a public user feature. ### Attack Path 1. An attacker, untrusted caller, or manipulated agent invokes the wrapper with an argument such as: ```bash bash scripts/music-search.sh search @/path/to/sensitive-file ``` 2. The wrapper removes the leading `@` and reads the entire file with `cat`. 3. The file contents replace the search keyword. 4. The JavaScript search engine embeds those contents in externally submitted search queries. 5. Sensitive values may consequently be disclosed to the web-search provider or Baidu and may also enter local cache files or diagnostic output. ### Impact Assessment The vulnerability permits disclosure of any file readable by the account running the skill. Depending on the execution environment, the exposed data could includ ...[truncated 361 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove public `@file` argument expansion and pass arguments literally. - If file-based query transport is required internally, expose it through a separate private interface rather than general CLI arguments. - Restrict readable files to a dedicated application-owned temporary directory. - Resolve the canonical path and verify that it remains under the permitted directory. - Verify file ownership, reject symbolic links, impose a small maximum file size, and delete temporary files after use. - Never submit file contents externally without explicit, informed user approval. - Add tests proving that paths such as `@/etc/passwd`, traversal paths, symlinks, and files outside the designated directory are rejected. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/music-search.ps1:48
Finding
Arbitrary Local File Disclosure Through PowerShell Argument Expansion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/music-search.ps1:48-60` **Vulnerability Type**: Unrestricted local file read followed by external transmission **Risk Level**: High ### Vulnerable Code ```powershell $processedArgs = @() foreach ($arg in $args) { if ($arg -match "^@(.+)$") { $filePath = $Matches[1] if (Test-Path $filePath) { $content = Get-Content $filePath -Raw -Encoding UTF8 $processedArgs += $content.Trim() } else { $processedArgs += $arg } } else { $processedArgs += $arg } } ``` ### Technical Analysis The PowerShell wrapper treats every argument beginning with `@` as a filesystem path and reads it without constraining the path to a safe directory. The resulting content is forwarded as a normal argument to `music-search.js`. When used as the search keyword, the file content is incorporated into external search requests. No user confirmation, path validation, file-size limit, or sensitive-file protection is applied. ### Attack Path 1. A caller runs: ```powershell powershell -File scripts/music-search.ps1 search "@/path/to/sensitive-file" ``` 2. `Test-Path` confirms that the target exists. 3. `Get-Content -Raw` reads the complete file under the privileges of the current process. 4. The content is passed to `music-search.js` as the search term. 5. The generated query is submitted to an external search service and may also be cached locally. ### Impact Assessment An attacker able to influence skill arguments can cause disclosure of files readable by the current Windows account. Potential targets include application configuration, cloud credentials, token files, SSH keys, and user documents. The issue does not bypass filesystem access controls directly, but it abuses the skill's existing access and network capabilities to move local information outside its intended trust boundary. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove implicit `@file` processing from arbitrary CLI arguments. - If this mechanism must remain, restrict it to an application-owned directory and compare canonical paths before reading. - Use `Get-Item` to reject directories, reparse points, symbolic links, and files not owned by the expected account. - Apply strict file-size and content-length limits. - Require an explicit file-input option and user confirmation before file contents can be sent to an external service. - Ensure sensitive input is neither written to the search cache nor included in diagnostic logs. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/music-search.js:892
Finding
Server-Side Request Forgery in URL Resolution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/music-search.js:892-903` **Vulnerability Type**: Unrestricted server-side URL retrieval with redirect following **Risk Level**: High ### Vulnerable Code ```javascript async function cmdResolve(args) { const url = args.positional[0]; if (!url) { outputError("请提供需要解析的 URL。用法: resolve <url>"); process.exit(1); } try { const resp = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(config.timeout), }); if (!resp.ok) throw new Error(`HTTP ${resp.status}`); const html = await resp.text(); ``` ### Technical Analysis The `resolve` command accepts a caller-controlled URL and retrieves it with the privileges and network position of the skill process. The implementation does not validate the scheme, hostname, port, resolved IP address, or redirect destinations. Because redirects are followed automatically, validating only the initial hostname would not be sufficient. An attacker-controlled public endpoint could redirect the request to localhost, a private address, a link-local service, or a cloud metadata endpoint. The response body is read without an explicit maximum-size limit. The code subsequently scans it for supported cloud-drive links, creating a response-disclosure channel when an internal page contains matching URLs. HTTP status and timing behavior may also provide a limited internal-network probing oracle. ### Attack Path 1. An attacker invokes: ```text music-search.js resolve <attacker-controlled-or-internal-URL> ``` 2. The URL directly targets an internal service, or a public attacker-controlled server redirects to one. 3. Node.js follows the redirect and sends the request from the host running the skill. 4. The response body is downloaded and searched for cloud-drive URLs. 5. Matching internal content is returned in the command's JSON output; status, error, and timing differences may reveal service availability even when ...[truncated 562 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Allow only `https:` URLs unless another scheme is explicitly required. - Resolve hostnames before making requests and reject loopback, link-local, private, multicast, unspecified, and reserved IPv4 and IPv6 ranges. - Repeat destination validation after every redirect and prevent DNS rebinding by connecting only to the validated address. - Disable automatic redirects and process a small, fixed number manually. - Prefer an allowlist of public domains that are required for the documented resolution feature. - Reject URLs containing credentials and restrict nonstandard ports. - Limit response size while streaming rather than calling `resp.text()` without a cap. - Apply short connection/read timeouts and a global request budget. - Do not return detailed network errors that unnecessarily improve internal-service enumeration. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deep_extract.py:146
Finding
Server-Side Request Forgery in Deep Page Extraction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deep_extract.py:146-154` **Vulnerability Type**: Unvalidated retrieval of externally discovered URLs **Risk Level**: High ### Vulnerable Code ```python def fetch_and_extract(page, scraper): """访问单个页面,提取所有网盘链接""" url = page.get('url', '') page_title = page.get('title', '') if not url: return [] try: r = scraper.get(url, timeout=8) ``` ### Technical Analysis The deep extractor retrieves URLs supplied through its input without validating their scheme, hostname, port, or resolved address. In normal operation, these URLs originate from search-engine output, which remains untrusted external input. A malicious search result can point directly to a sensitive network destination or to an attacker-controlled endpoint that redirects there. `cloudscraper` uses the Requests ecosystem, which normally follows redirects for GET requests. The JavaScript domain blacklist is keyword-based and is not a network security boundary; it neither rejects private addresses nor validates redirect targets. ### Attack Path 1. An attacker causes a crafted page to appear in search results for a likely music-resource query. 2. The result receives a sufficient relevance score and is selected for deep extraction. 3. The selected URL points to, or redirects toward, an internal or link-local service. 4. `scraper.get` sends the request from the skill host. 5. The extractor scans the internal response for cloud-drive and magnet links. 6. Any matching data is emitted as an extraction result; request outcomes are also written to diagnostics. The extractor can also be invoked directly with attacker-supplied JSON page objects through its standard input, removing the need for search-result manipulation where that interface is exposed. ### Impact Assessment The issue permits network access from the skill's execution environment to otherwise inaccessible HTTP services. It can expose supported link p ...[truncated 353 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Introduce a shared URL-security validator before every request. - Permit only HTTP or, preferably, HTTPS public destinations required by the feature. - Resolve all A and AAAA records and reject private, loopback, link-local, reserved, multicast, and unspecified ranges. - Disable automatic redirects; validate each redirect destination before following it. - Reject ambiguous numeric hosts, embedded credentials, malformed URLs, and unsupported ports. - Add a bounded streaming response reader and enforce content-type and response-size limits. - Treat search results and standard-input page objects as untrusted data. - Replace the keyword-based domain blacklist with an allowlist or a robust public-address policy. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/music-search.sh:24
Finding
Arbitrary Command Execution Through Sourced Environment File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/music-search.sh:24-31` **Vulnerability Type**: Executable configuration file **Risk Level**: Medium ### Vulnerable Code ```bash # ---- Load .env configuration ---- if [ -f "$SKILL_DIR/.env" ]; then set -a # shellcheck disable=SC1091 source "$SKILL_DIR/.env" 2>/dev/null || true set +a fi ``` ### Technical Analysis Bash `source` interprets the entire `.env` file as shell code rather than parsing it as configuration data. Consequently, command substitutions, function definitions, redirections, pipelines, and arbitrary shell statements execute whenever the wrapper starts. The documentation encourages users to edit `.env` as a collection of configuration values, which creates an expectation that it is data-only. If another process, package operation, archive extraction, or user can modify that file, invoking any skill command becomes a code-execution trigger. Redirecting errors and appending `|| true` suppresses visible failures but does not prevent payload execution. ### Attack Path 1. An attacker gains the ability to create or modify the skill's `.env` file. 2. The attacker inserts shell syntax, for example a command substitution within an apparent assignment. 3. A user or agent invokes any command through `music-search.sh`. 4. The wrapper sources `.env` before starting Node.js. 5. The injected command executes with the same operating-system permissions as the skill process. ### Impact Assessment Successful exploitation provides arbitrary command execution under the account running the skill. The attacker can read or modify that account's files, access its environment and credentials, initiate network connections, and alter application state. This finding does not establish that `.env` is currently attacker-writable; exploitation depends on an attacker obtaining write access through another channel. Sourcing it nevertheless turns any such configuration compromise into immediate code e ...[truncated 15 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never use `source` to load a data-only `.env` file. - Implement a parser that accepts only an allowlist of required variable names and literal `KEY=VALUE` records. - Reject invalid variable names, duplicate keys, command substitutions, shell metacharacters, and unsupported quoting. - Set the approved environment variables explicitly rather than enabling automatic export for arbitrary names. - Require restrictive ownership and permissions on the configuration file. - Align the Unix wrapper with the PowerShell wrapper's data-oriented parsing behavior, while adding a strict key allowlist to both. - Add tests using values containing `$()`, backticks, semicolons, redirections, and newlines to verify that they are never executed. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Automatic Installation of an Unpinned Third-Party Dependency<![CDATA[ ## Vulnerability Details **File Locations**: `requirements.txt:1` and `scripts/music-search.js:578-592` **Vulnerability Type**: Uncontrolled dependency resolution and automatic package installation **Risk Level**: Medium ### Vulnerable Code `requirements.txt`: ```text cloudscraper>=1.2.71 ``` `scripts/music-search.js`: ```javascript // 4. Auto-create venv and install cloudscraper try { process.stderr.write("[deep-search] 首次使用,正在安装 cloudscraper...\n"); const reqFile = path.join(skillDir, "requirements.txt"); await execFileAsync(python3, ["-m", "venv", path.join(skillDir, ".venv")], { timeout: 30000, }); const pipPython = venvPython; await execFileAsync(pipPython, ["-m", "pip", "install", "-q", "-r", reqFile], { timeout: 60000, }); _pythonPath = venvPython; process.stderr.write("[deep-search] cloudscraper 安装完成\n"); return _pythonPath; } catch (err) { ``` ### Technical Analysis The dependency constraint permits any `cloudscraper` release at or above version `1.2.71`. No lock file, transitive dependency pins, integrity hashes, or explicit trusted package index are provided. When the package is not already importable, normal skill execution automatically creates a virtual environment and invokes pip. This downloads and installs whichever versions the package resolver selects at that time. Package installation and import can execute third-party code under the user's account. This is a supply-chain weakness rather than evidence that the currently named package is malicious. The risk is that the effective dependency set can change after the skill has been audited. ### Attack Path 1. Deep search starts on a host where `cloudscraper` is not available. 2. `ensurePythonEnv` automatically creates `.venv`. 3. Pip resolves `cloudscraper>=1.2.71` and all transitive dependencies from its configured index. 4. A compromised future release, compromised transitive dependency, package-index attack, or resolver substitution supplies mal ...[truncated 539 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `cloudscraper` to an exact reviewed version. - Generate a lock file that pins every transitive dependency. - Require cryptographic hashes for all downloaded distributions, such as with pip's `--require-hashes`. - Configure an explicitly trusted package index or internally reviewed artifact repository. - Prefer pre-provisioning dependencies during a controlled installation phase rather than downloading code automatically during a search command. - Require explicit user approval before creating an environment or installing packages. - Record and verify the dependency manifest used to build the environment. - Add routine dependency vulnerability scanning and a controlled review process before updating pins. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose says the skill searches music resources from specific cloud-drive providers, but the documented output also includes `magnet` links and describes generic deep crawling and redirect resolution. This mismatch hides materially broader collection and link-extraction behavior, which increases the chance of unsafe invocation, policy bypass, or use for piracy/malware distribution beyond the stated scope.

Credential Access

High
Category
Privilege Escalation
Content
exit 1
}

# ---- Load .env configuration ----
$envFile = Join-Path $SkillDir ".env"
if (Test-Path $envFile) {
    Get-Content $envFile | ForEach-Object {
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
}

# ---- Load .env configuration ----
$envFile = Join-Path $SkillDir ".env"
if (Test-Path $envFile) {
    Get-Content $envFile | ForEach-Object {
        $line = $_.Trim()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
}

# ---- Load .env configuration ----
$envFile = Join-Path $SkillDir ".env"
if (Test-Path $envFile) {
    Get-Content $envFile | ForEach-Object {
        $line = $_.Trim()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
exit 1
fi

# ---- Load .env configuration ----
if [ -f "$SKILL_DIR/.env" ]; then
  set -a
  # shellcheck disable=SC1091
Confidence
91% confidence
Finding
The script automatically loads and sources a .env file from the skill directory using the shell. Because source executes shell syntax rather than safely parsing key/value pairs, a modified .env can run arbitrary commands in the user's environment when the skill starts. In a skill ecosystem where package contents may be updated or tampered with, this increases risk beyond normal configuration loading.

Credential Access

High
Category
Privilege Escalation
Content
fi

# ---- Load .env configuration ----
if [ -f "$SKILL_DIR/.env" ]; then
  set -a
  # shellcheck disable=SC1091
  source "$SKILL_DIR/.env" 2>/dev/null || true
Confidence
96% confidence
Finding
The specific statement source "$SKILL_DIR/.env" causes the shell to execute the contents of the .env file. An attacker who can modify that file can achieve arbitrary code execution at skill launch, inheriting the user's privileges and exported environment. The surrounding '|| true' may also suppress errors and make malicious or malformed behavior less visible.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill declares executable behavior that uses environment access and live network activity, but it does not define an explicit tool/permission scope. That creates a transparency and containment problem: an agent or reviewer cannot easily tell what capabilities are intended, and the skill may be granted broader execution than necessary.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The description lists trigger phrases including "找音乐" and especially "找歌", which are common conversational requests rather than narrowly scoped activation terms. Because the manifest does not provide exclusion conditions or tighter context constraints, these phrases may overlap with ordinary user speech and trigger the skill too broadly.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill performs live crawling of third-party pages, installs Python dependencies, and uses deep page fetching, but the top-level description does not prominently warn users that invocation causes active network requests and content retrieval. This lack of up-front disclosure can lead to unexpected outbound access to untrusted sites and exposure to malicious pages or sensitive browsing contexts.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring describes the skill entirely in Chinese, and later user-visible errors and status output are also Chinese-only. This imposes a specific language/locale on users without opt-in or any documented justification that the skill is region-specific, matching the language policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill is described as searching cloud-drive music resources, but the code also extracts BitTorrent magnet links via MAGNET_PATTERN and returns them as results. This expands the capability beyond the declared scope, increasing legal/compliance risk and enabling distribution workflows the user and platform may not have expected or approved.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The skill launches external bash and Python subprocesses to perform search and extraction, adding interpreter execution and dependency on external scripts outside the main Node.js process. While execFile avoids classic shell injection, this still increases attack surface because compromised helper scripts, manipulated environment variables, or unexpected interpreter behavior can lead to unauthorized code execution or data access.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill automatically creates a Python virtual environment and installs dependencies at runtime, which introduces network access and code execution beyond its declared purpose of searching for music links. This expands the trust boundary significantly: package installation can fetch and execute unpinned third-party code, and doing so implicitly at runtime makes behavior less auditable and more dangerous in restricted or sensitive environments.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code presents its primary usage text and multiple user-facing messages entirely in Chinese, which imposes a specific language on users without any opt-in or alternative locale path. The policy for natural-language behavior requires either user choice or a clearly documented, justified locale constraint.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Lines L25-L39 automatically ingest configuration from .env and set process environment variables, which can include sensitive credentials or alter downstream runtime behavior. Although the code is straightforward, there is no confirmation prompt, visible warning, or explanatory comment indicating to users that local secret-bearing configuration will be loaded.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This shell script includes natural-language comments and an emitted error message in Chinese, with no indication that another language can be selected. Under the policy rule for language/locale, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The note instructs users to search using Chinese artist and album or song names for best results, which effectively imposes a language preference in the skill guidance. The file does not offer an opt-in language choice or explain that the skill is intentionally limited to a Chinese-language corpus or region-specific use case.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cloudscraper>=1.2.71
Confidence
89% confidence
Finding
The dependency is specified with a lower bound only (`cloudscraper>=1.2.71`), which allows installation of any newer version without review. This weakens build reproducibility and can unintentionally pull in a compromised, malicious, or breaking upstream release, increasing supply-chain risk for a skill that fetches external resources from the internet.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/music-search.js:343

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/music-search.js:35