Back to skill

Security audit

ClawVoyant

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to do what it claims: search YouTube and retrieve transcripts, with no evidence of hidden data theft, persistence, or destructive behavior.

Reasonable to install if you accept that it sends search terms and video IDs to external services. The publisher should pin dependency versions, add bounds for max_results, and fix the install command so installation does not accidentally start the server.

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 (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:9
Finding

Unpinned Third-Party Dependencies Permit Unreviewed Package Versions

Content
View full analysis
=3.10" pip: - duckduckgo_search>=6.0.0 - youtube-transcript-api>=0.6.0 - fastmcp>=0.1.0 install: "python scripts/server.py --install" ``` ### Technical Analysis All three Python dependencies use open-ended minimum-version constraints. No upper bounds, exact version pins, lockfile, or cryptographic package hashes are present in the audited project. Consequently, a future installation can resolve to dependency versions that were not present when the skill was reviewed. Python packages can execute code during installation or when imported. The application imports all three declared packages at module initialization in `scripts/server.py`. If an upstream package account, release process, or distribution channel is compromised, a malicious version satisfying these constraints could be installed and subsequently executed. This finding does not establish that the named packages are currently malicious. The risk arises from allowing future, unreviewed releases to enter the execution environment automatically. ### Attack Path 1. An attacker compromises an allowed upstream package, maintainer account, or package publication process. 2. The attacker publishes a malicious version greater than or equal to the minimum version declared in `SKILL.md`. 3. A user or deployment platform installs the skill and resolves dependencies without a lockfile or hash validation. 4. The package manager selects the attacker-controlled release because it satisfies the open-ended constraint. 5. Malicious code executes during package installation or when `scripts/server.py` imports the dependency. 6. The payload operates with the privileges and environmental access of the account running the installation or MCP server. ### Impact Assessment Successful exploitation co ...[truncated 396 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/server.py:26
Finding

Unbounded Search Result Count Enables Resource Exhaustion

Content
View full analysis
List[Dict]: """Search YouTube and return a list of video details.""" results = [] search_query = f"{query} YouTube" raw_results = self.ddgs.text(search_query, max_results=max_results * 4) ``` The externally exposed MCP tool passes the caller-controlled value directly to the search method: ```python @mcp.tool() def search_youtube(query: str, max_results: int = 5) -> str: """ Search YouTube for videos. Returns a list of titles, URLs, and descriptions. """ results = cv.search(query, max_results=max_results) ``` ### Technical Analysis The MCP interface accepts a caller-controlled `max_results` integer without validating its range. The value is multiplied by four before being passed to the DuckDuckGo search client. A very large positive value can cause the server or its dependency to request, receive, iterate over, and format an excessive number of results. The code provides no explicit upper bound, request timeout, response-size limit, concurrency control, or per-caller rate limit. Even if the upstream service imposes its own limit, repeated oversized calls can still consume server connections, processing time, and upstream request quota. The final number of accepted YouTube results is nominally limited by `max_results`, but that does not mitigate the initial external request because the multiplied value is supplied before local filtering occurs. ### Attack Path 1. An attacker or malfunctioning MCP client invokes `search_youtube`. 2. The caller supplies an extremely large positive integer as `max_results`. 3. The tool forwards the value without validation to `ClawVoyant.search`. 4. The code multiplies the value by four and sup ...[truncated 838 chars]
Remediation
View remediation
List[Dict]: if not isinstance(max_results, int) or isinstance(max_results, bool): raise ValueError("max_results must be an integer") if not 1 <= max_results <= MAX_RESULTS: raise ValueError(f"max_results must be between 1 and {MAX_RESULTS}") # Continue with the bounded request. ``` ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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