T09 · Insecure Skill Coding Practices
- Location
index.js:280- Finding
Concurrent quota updates allow provider limits to be exceeded
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to perform its advertised search and quota functions, but it persistently records raw searches and result summaries while broadly routing queries to external providers without enough user control.
Install only if you are comfortable with search terms and partial results being stored locally for up to 30 days and with queries being sent to third-party search/API providers. Avoid using it for secrets, private customer data, regulated content, or sensitive internal investigations unless logging is disabled or redacted and dependency installation is pinned/reviewed.
index.js:280Concurrent quota updates allow provider limits to be exceeded
package.json:6Unpinned dependency installation creates a mutable supply-chain boundary
The documented behavior claims search routing, API use, circuit breaking, and fallback logic, while the analyzed behavior reportedly performs direct quota-file modification and backup instead. That mismatch is security-relevant because operators may approve the skill for low-risk web search while it actually changes persistent local state, creating opportunity for unauthorized quota resets, audit evasion, or policy bypass.
The examples and log schema explicitly state that manual chat searches are written to daily JSONL files with raw query content and response summaries. Manual/chat queries are especially likely to contain sensitive conversational content, so persisting them to disk substantially raises the risk of local data leakage, unauthorized access by other users/processes, and long-tail compliance issues.
The skill documentation advertises capabilities that rely on network access and environment-held API keys, but it does not declare an explicit tool scope or permission boundary. In an agent ecosystem, that weakens least-privilege controls and makes it easier for the skill to be granted broader access than users or operators expect.
The skill states that it logs all searches but does not provide a clear, prominent privacy warning at the point of use. Users or calling agents may unknowingly send sensitive prompts, identifiers, or business data into a system that persists them locally, which creates avoidable confidentiality and compliance risk.
Persistent logging of raw search queries and response summaries creates a durable record of natural-language inputs that may contain personal data, secrets, internal research, or regulated content. Because this skill is intended for broad web-search use, the likelihood of collecting sensitive user-entered text is materially higher than in a narrowly scoped operational tool.
The invocation guidance says to use the skill for essentially any web search need, which can cause over-triggering by agents and unnecessary transmission/logging of user queries. In this skill, that broad routing advice is more dangerous because searches may hit external providers and are also persisted to daily logs, increasing privacy and data-exposure risk.
User search queries are transmitted to third-party services such as Gemini, Brave, and web search engines, which can expose sensitive user intent or embedded confidential data outside the local environment. While external transmission is inherent to a search skill, the absence of disclosure or controls makes this a real privacy/security concern in agent workflows.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
const encoded = encodeURIComponent(query);
const endpoint = `https://api.search.brave.com/res/v1/web/search?q=${encoded}`;
let response;
try {
The skill persistently logs raw queries and response summaries to local JSONL files, which can capture sensitive user prompts, searched entities, and provider-derived content unrelated to core routing. In an agent environment, search queries often contain confidential investigation context, so local persistence increases exposure to other local users, backup systems, or later compromise.
The manifest frames the skill as API-based routing across Gemini and Brave with web_fetch as a fallback, but the general search path is implemented with Google and Bing scraping as the primary behavior. This is a semantic mismatch because a major execution path does something materially different from the described routing model.
The main search flow records query text, provider selection, errors, and response summaries without any user-facing notice or consent mechanism in this code path. Because this occurs on every search, it creates a systematic privacy leak and retention risk, especially for sensitive agent tasks.
The documentation states that corrupted JSON is deleted and replaced with a fresh default file, which is destructive recovery behavior that can silently erase quota/accounting state. In this skill's context, that can invalidate usage tracking, reset limits unexpectedly, and undermine quota enforcement or auditability if corruption is triggered intentionally or occurs during concurrent access.
The parameter documentation at L052 and the invalid-provider error at L277 state that only gemini or brave are valid values for force_provider. Immediately after, L278 documents a separate Perplexity is not yet implemented error path, which implies support or recognition for an undeclared provider and contradicts the stated interface.
The manifest mentions a web_fetch fallback without describing that the code uses specific third-party search engines, including DuckDuckGo, as part of the fallback logic. While still related to search, the actual behavior is broader and more specific than the declared description.
The dependency is specified with a caret range (^4.1.2), which permits automatic installation of newer minor and patch releases. That weakens supply-chain reproducibility and can unexpectedly pull in a compromised or breaking upstream version if the lockfile is absent, regenerated, or ignored in deployment.
"description": "OpenClaw AgentSkill for intelligent search routing with quota management",
"main": "index.js",
"dependencies": {
"proper-lockfile": "^4.1.2"
},
"scripts": {
"start": "node index.js",