Back to skill

Security audit

Films Search

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it performs broad web scraping, follows arbitrary URLs, and auto-installs an unpinned Python dependency with insufficient safety controls.

Review before installing. Use only in a restricted environment with no access to internal networks or sensitive local credentials, avoid running resolve on untrusted arbitrary URLs, and prefer manual audited dependency setup with pinned versions. Treat returned cloud-drive links as third-party content and verify legality and safety yourself.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/film-search.js:909
Finding
Unrestricted URL Resolution Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/film-search.js:909-923` **Additional Location**: `scripts/deep_extract.py:145-158` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```javascript async function cmdResolve(args) { const url = args.positional[0]; if (!url) { outputError("Please provide the URL to resolve."); process.exit(1); } try { // Fetch the page 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(); ``` The Python extraction path contains a similar unrestricted request: ```python def fetch_and_extract(page, scraper): """Visit one page and extract all cloud-drive links.""" url = page.get('url', '') page_title = page.get('title', '') if not url: return [] try: r = scraper.get(url, timeout=8) if r.status_code != 200: sys.stderr.write(f'[extract] {url} -> HTTP {r.status_code}\n') return [] html = r.text ``` ### Technical Analysis The `resolve` command accepts a user-controlled URL and passes it directly to `fetch`. It does not validate: - The URL scheme - The destination hostname or resolved IP address - Loopback, private, link-local, multicast, or reserved networks - Cloud instance metadata addresses - Redirect destinations - DNS rebinding between validation and connection Because redirects are explicitly followed, an apparently public URL can redirect the request to an internal service. The Python extraction component has the same underlying weakness and accepts page URLs from JSON supplied through standard input. The response body is parsed for cloud-drive links rather than returned in full. This limits direct response disclosure, but does not prevent SSRF. An attacker may still infer service availability through st ...[truncated 1435 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse URLs with a strict URL parser and allow only `https:` unless plain HTTP is explicitly required. 2. Reject URLs containing credentials, malformed hostnames, or nonstandard encodings. 3. Resolve the hostname before connecting and reject every address in loopback, private, link-local, multicast, unspecified, and reserved ranges for both IPv4 and IPv6. 4. Explicitly block cloud metadata destinations, including link-local metadata addresses. 5. Disable automatic redirects and validate each redirect destination using the same controls before following it. 6. Protect against DNS rebinding by connecting only to the validated resolved address while preserving the expected hostname for TLS verification. 7. Prefer an allowlist of public domains appropriate to the resolver's intended purpose. 8. Apply the same validation routine to `deep_extract.py`, including URLs accepted from standard input and URLs discovered through search results. 9. Run outbound requests in a network sandbox that cannot access internal networks or metadata services. 10. Limit response size and supported content types to reduce secondary denial-of-service risks. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/film-search.sh:26
Finding
Configuration File Is Executed as Arbitrary Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/film-search.sh:26-32` **Vulnerability Type**: Arbitrary command execution through unsafe configuration loading **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 The shell wrapper uses `source` to load `.env`. In Bash, `source` does not parse a passive environment-variable format; it executes the file as a shell program in the current process. Consequently, an `.env` file can contain command substitutions, shell functions, redirections, pipelines, or arbitrary commands. This behavior is more permissive than the documented purpose of the file, which presents it as a location for simple configuration assignments. Suppressing standard error and appending `|| true` does not prevent code execution. Instead, it can hide visible signs that malicious or malformed commands were processed. ### Attack Path 1. An attacker gains the ability to create or modify `.env` in the project directory. This may occur through a compromised archive, shared workspace, unsafe update process, or social engineering that instructs a user to install a configuration file. 2. The attacker adds shell syntax to the file, for example: ```bash FILM_SEARCH_DEEP_ENABLED="$(attacker_controlled_command)" ``` 3. A user invokes the Skill through the documented `film-search.sh` wrapper. 4. The wrapper executes `source "$SKILL_DIR/.env"`. 5. The command embedded in `.env` runs before the Node.js application starts. ### Impact Assessment The injected commands execute with the operating-system privileges of the user or service account running the Skill. They can access all files, environment variables, credentials, and network resources available to that account. The vulnerability does not independently elevate privileges beyond the invoking ...[truncated 144 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `source`, `.`, `eval`, or command substitution to parse `.env`. 2. Implement a non-executing parser that accepts only a strict allowlist of expected keys, such as: - `FILM_SEARCH_PREFERRED_PAN` - `FILM_SEARCH_DEEP_ENABLED` - `FILM_SEARCH_DEEP_MAX_PAGES` - `FILM_SEARCH_DEEP_CONCURRENCY` 3. Require each entry to match a strict `KEY=VALUE` grammar. 4. Reject shell metacharacters, command substitutions, function declarations, redirections, and multiline values. 5. Validate each value by type and range before exporting it. 6. Prefer loading configuration directly in JavaScript with a parser that does not perform variable expansion or shell evaluation. 7. Verify that `.env` is a regular file owned by the expected user and is not writable by untrusted users. 8. Report malformed configuration rather than suppressing all errors. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Automatic Installation Uses an Unpinned and Unverified Dependency<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1` **Additional Location**: `scripts/film-search.js:584-600` **Vulnerability Type**: Insecure dependency installation and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```text cloudscraper>=1.2.71 ``` The application automatically installs the dependency when it is unavailable: ```javascript // 4. Auto-create venv and install cloudscraper try { process.stderr.write("[deep-search] First use; installing 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 installation completed\n"); return _pythonPath; } catch (err) { throw new Error(`Python environment initialization failed: ${err.message}.`); } ``` ### Technical Analysis The version constraint `cloudscraper>=1.2.71` allows `pip` to install any later compatible version available at installation time. No cryptographic hashes are supplied, and the package index is not explicitly constrained to an approved source. The installation occurs automatically during normal deep-search use. Python packages can execute code as part of their build or installation process, and their imported modules execute code within the application process. Therefore, the effective dependency code can change after the Skill itself has been reviewed. This finding does not establish that the current `cloudscraper` package is malicious. The vulnerability is the mutable, automatic, and unverified supply-chain trust decision. ### Attack Path 1. The Skill runs on a system where `cloudscraper` is not already installed and the project virtual environment does not exist. 2. A user invokes deep-searc ...[truncated 1054 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to an exact reviewed version rather than using a lower-bound constraint. 2. Generate and commit cryptographic hashes for every package and transitive dependency. 3. Install with `pip --require-hashes` from a locked requirements file. 4. Use a controlled, trusted package index or an internally mirrored repository. 5. Require explicit user or administrator approval before downloading and installing packages. 6. Prefer installation during a controlled deployment phase rather than during normal Skill execution. 7. Audit and lock all transitive dependencies, not only `cloudscraper`. 8. Run installation and extraction under a low-privilege account in a restricted environment. 9. Add automated dependency vulnerability and integrity scanning to the release process. ]]>
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 (16)

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
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
fi

# ---- Load .env configuration ----
if [ -f "$SKILL_DIR/.env" ]; then
  set -a
  # shellcheck disable=SC1091
  source "$SKILL_DIR/.env" 2>/dev/null || true
Confidence
97% confidence
Finding
The script sources a local .env file directly into the shell with `source "$SKILL_DIR/.env"`, which treats the file as executable shell code rather than passive key-value data. If an attacker can modify that file, arbitrary commands can run in the user's context before the Node script starts, potentially exposing credentials or executing malicious actions.

Credential Access

High
Category
Privilege Escalation
Content
if [ -f "$SKILL_DIR/.env" ]; then
  set -a
  # shellcheck disable=SC1091
  source "$SKILL_DIR/.env" 2>/dev/null || true
  set +a
fi
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill documents capabilities that require network access and local environment interaction, including web scraping and automatic dependency installation, but it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens least-privilege controls and can cause an agent or host runtime to invoke broader capabilities than users expect, especially when the skill fetches third-party content and modifies `.venv` automatically.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are very broad, covering common requests like finding movies or download links, which raises the chance the skill is invoked unintentionally. In this skill, accidental invocation is more concerning because activation can lead to network searches, scraping of third-party pages, and facilitation of access to potentially infringing content.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly promotes real-time crawling, deep scraping, and redirect resolution across third-party resource pages, but it does not give a clear user-facing warning that using it will contact external sites and follow untrusted links. That omission can expose users or agents to privacy leakage, malicious pages, and unsafe content sources, especially given the skill’s focus on harvesting file-sharing links.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The agent workflow says that when a user asks to find a movie, the agent should execute a search directly, but it does not define strong boundaries or confirmation requirements. Because the search may perform deep scraping and later resolve redirect links, ambiguous invocation increases the risk of unintended external requests and interaction with untrusted sites.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The note says searches are recommended to use Chinese titles for best results, and the overall skill description and examples are entirely Chinese-centric without offering a language choice. This creates an implicit locale/language constraint that is not presented as optional or justified as a region-specific tool.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script issues outbound HTTP requests to both search-engine result pages and arbitrary result URLs, then follows up by fetching those pages concurrently. In this skill’s context, that means user-triggered searches can cause undisclosed network access to untrusted third-party sites, exposing the operator’s IP/user-agent and creating SSRF-like risk if untrusted input can influence the page list or queries.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill expands its privileges beyond simple film-resource search by creating Python virtual environments, invoking Python and shell subprocesses, and installing dependencies at runtime. This increases the attack surface substantially: dependency installation can execute arbitrary setup/install-time code, and subprocess invocation introduces supply-chain and environment-manipulation risks if the host or package sources are untrusted.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Automatically creating a virtual environment and installing Python packages without explicit user confirmation is risky because package installation executes code from external artifacts and may alter the host environment. In a security-sensitive agent setting, silent installation can expose the system to dependency confusion, typosquatting, compromised mirrors, or malicious transitive packages.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The resolve command retrieves arbitrary user-supplied URLs and processes their contents, giving the skill a generic outbound fetch capability unrelated to a narrowly scoped media-search feature. In practice this can be abused for SSRF-style access to internal services, metadata endpoints, or other network-reachable resources from the host running the skill.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The skill states that Python dependencies will be automatically installed into `.venv` on first run, but it does not present this as a significant local-environment modification requiring user awareness or consent. Silent installation increases supply-chain and environment-integrity risk, particularly when combined with network-fetched packages and execution of scraping tooling.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cloudscraper>=1.2.71
Confidence
88% confidence
Finding
The dependency is specified with a lower-bound only (cloudscraper>=1.2.71), which allows future unreviewed versions to be installed. This creates supply-chain risk because a compromised, malicious, or breaking upstream release could be pulled into the skill without notice, and this skill’s purpose of fetching external resource links increases exposure to untrusted network interactions.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The script's human-facing description, usage errors, and log/error messages are written exclusively in Chinese, which imposes a specific language/locale on users. There is no indication of opt-in, fallback, or documented justification for this locale restriction.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The script's visible usage text and several error/status messages are presented only in Chinese, which imposes a specific language on users. There is no indication of locale selection, fallback behavior, or documentation that this tool is intentionally restricted to Chinese-speaking users.