T09 · Insecure Skill Coding Practices
- Location
scripts/run.py:123- Finding
Tool inputs and results are persisted in a plaintext cache
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is not clearly malicious, but it advertises a broad live ToolRouter gateway while shipping a mock implementation that can persist tool inputs and results locally in plaintext.
Review carefully before installing. Do not send secrets, customer data, credentials, private targets, or sensitive prompts through this skill unless caching is disabled or redesigned. Treat the advertised 150+ live tools and MCP gateway claims as unsupported by the shipped code, and require clear scoping, authentication, retention controls, and accurate documentation before using it in a real workflow.
scripts/run.py:123Tool inputs and results are persisted in a plaintext cache
The skill markets itself as a live gateway to 150+ tools with dynamic native exposure, scanning, research, and MCP transport, but the analysis indicates the implementation is largely simulated and only exposes limited wrappers/mock entries. This mismatch is dangerous because users may rely on nonexistent security controls or functional behavior, route sensitive data to a component they misunderstand, or assume vetted tool execution when the real behavior is different.
The skill describes capabilities that require environment access, file read/write, and shell/MCP execution, but it does not declare any top-level scope restrictions such as permissions or allowed-tools. That creates an overly broad trust boundary: consumers may enable a gateway that can access secrets, write local cache/log files, and launch an MCP server without explicit policy constraints.
Advertising that users can call any ToolRouter tool after discovery establishes an effectively unbounded execution surface through a remote catalog. In this context, that is dangerous because the available tools can change dynamically, may include risky capabilities such as scanning or scraping, and are not restricted by a documented allowlist or approval boundary.
Once catalog is fetched, you can call any ToolRouter tool:
# Competitor research
The described cache and usage log behavior implies persistent storage of data derived from every tool invocation, which may include highly sensitive user-provided content or data returned from third-party services. Even if only hashes are stored for some fields, broad retention of invocation metadata can still enable correlation, forensic recovery, or leakage from the local filesystem.
The skill documents caching and usage logging but does not warn that tool inputs and related metadata may be retained locally, even when those inputs could contain API targets, research data, prompts, credentials, or other sensitive content. Users may unknowingly send confidential material to third-party tools and also leave durable local traces, increasing exposure and incident impact.
Running the gateway as an MCP server so other clients can use all ToolRouter tools further expands the trust boundary and may turn the skill into a general-purpose capability broker. Without authentication, authorization, and tool-level restrictions, this can enable unintended third-party access to broad remote actions under the host's API key and local environment.
toolrouter-gateway --mcp
Other MCP clients can then connect and use all ToolRouter tools as MCP resources.
## Pricing
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.
## Pricing
$49/month. Includes:
- Unlimited tool calls (you pay ToolRouter usage separately; most tools cost fractions of a cent)
- Caching reduces your ToolRouter bill
- Usage analytics
- Priority support
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def load_config():
default = {
"api_url": "https://api.toolrouter.com/mcp",
"cache_ttl_minutes": 1440,
"enable_caching": True,
"timeout_seconds": 60,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def load_config():
default = {
"api_url": "https://api.toolrouter.com/mcp",
"cache_ttl_minutes": 1440,
"enable_caching": True,
"timeout_seconds": 60,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def load_config():
default = {
"api_url": "https://api.toolrouter.com/mcp",
"cache_ttl_minutes": 1440,
"enable_caching": True,
"timeout_seconds": 60,
The code stores full tool input data and results in a local cache file by default, without sanitization, minimization, encryption, or explicit user disclosure. In this skill context, inputs may include sensitive research targets, scan targets, creative briefs, or other confidential material, so local persistence increases the risk of data exposure to other local processes, users, or future prompts/tools reading the workspace.
The usage log persistently records tool names, timestamps, and deterministic hashes of request inputs without clear disclosure or retention controls. Although the raw input is not written here, the metadata can still reveal sensitive activity patterns, correlate repeated requests, and expose use of security-related tools in a shared or monitored workspace.
The docstring says the function fetches the ToolRouter tool catalog via MCP or HTTP, which implies live remote retrieval. However, the implementation explicitly returns a static mock catalog and does not perform any MCP or HTTP operation, so the inline documentation contradicts actual behavior.
The function docstring states that it proxies a call to ToolRouter, suggesting a real upstream invocation. In reality, the code never contacts ToolRouter and instead returns a local placeholder result, which is an active contradiction between documentation and behavior.
No suspicious patterns detected.