T09 · Insecure Skill Coding Practices
- Location
search.py:33- Finding
Search Queries and Results Are Persisted in Plaintext
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This search skill needs Review because it advertises real search integrations but can return fabricated results and stores search history locally in plaintext.
Install only after reviewing the code and documentation carefully. Do not rely on it for live search until the mock oxylabs paths are removed or clearly disabled, and avoid sensitive queries unless caching is disabled or the cache location is protected. Treat batch inputs as data that may be sent to external providers, and prefer pinned dependencies in an isolated environment.
search.py:33Search Queries and Results Are Persisted in Plaintext
requirements.txt:2Dependencies Are Installed Without Exact Version or Integrity Pinning
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"num": min(num_results, 10) # API max is 10
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"num": min(num_results, 10) # API max is 10
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"num": min(num_results, 10)
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"num": min(num_results, 10)
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
The declared description presents a search capability with caching, rate limiting, and API-based optimization. The supplied code chunk does not perform Google searches, call OpenClaw tools, interact with APIs, or implement rate limiting/cost optimization logic. Instead, it acts as a debugging script for cache-key generation and local cache database inspection. While cache-related behavior is loosely related, the primary purpose of this chunk is materially different from the declared search functionality, so this is a mismatch.
The declared description is about a runtime Google Search capability with caching, rate limiting, and cost optimization. The supplied code chunk does not implement search, caching, API usage, rate limiting, or cost optimization. Instead, it is a release-preparation/publishing helper script for validating project structure and guiding publication to ClawHub. This is a materially different primary purpose, so the description does not accurately represent the behavior of this code chunk.
The declared description says the skill itself provides Google Search with caching, rate limiting, and cost optimization. However, the supplied code chunk does not implement a search capability; it imports SearchEngine from elsewhere and acts only as a verification/test script. Its primary purpose is testing basic behavior, cache hits, timing, and error handling, then reporting pass/fail. While these tests are related to the declared search skill, this chunk’s actual function is materially different from the declared operational purpose. There is no evidence here of direct Google Search implementation, OpenClaw tool use, rate limiting logic beyond sleep delays in tests, or real cost optimization behavior.
The description claims a Google Search skill using OpenClaw tools and free APIs with caching, rate limiting, and cost optimization. Parts of that are accurate: the code does implement SQLite-based caching, a basic rate limiter, method ordering for cost optimization, and integrations for Google Custom Search and DuckDuckGo. However, the core declared purpose is materially overstated or inaccurate. The highest-priority OpenClaw/Oxylabs path is not a real integration and instead returns hardcoded mock results. The lightweight HTTP search is also only a stub. As a result, the actual behavior is not a dependable Google search tool, but rather a partially implemented search wrapper whose most likely successful path may be DuckDuckGo or cached data. Additionally, the CLI exposes a method-selection option that is never used, indicating behavior does not fully match its own interface. These are material mismatches in primary functionality rather than minor implementation details.
The description says this is a Google Search skill with intelligent caching, rate limiting, and cost optimization using OpenClaw tools and free APIs. The code does implement caching via SQLite and does attempt cost-optimized backend selection. However, there is no actual rate limiting logic despite a MAX_REQUESTS_PER_MINUTE constant being defined. The supposed 'real OpenClaw integration' function only prints a message and returns mock results; it does not invoke a real OpenClaw tool in this code chunk. The engine is also not strictly a Google search skill: it may use DuckDuckGo's API or a simple fallback link, and its first-priority path is mock oxylabs/OpenClaw output. These are material mismatches between declared purpose and actual behavior.
The declared description presents this as a search skill implementation with caching, rate limiting, and cost optimization. The supplied code chunk is instead a diagnostic/test harness. One function only prints what a production tool call would look like and returns a simulated availability result; the other imports an external SearchEngine and runs sample queries against it. Any actual search, caching, or optimization behavior would be in the unseen search module, not in this chunk. Therefore the code's primary purpose is materially different from the declared purpose, making this a mismatch.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
lxml>=4.9.0 # Faster HTML parsing
# Optional: For advanced features
# python-dotenv>=1.0.0 # For .env file support
# aiohttp>=3.8.0 # For async requests (optional)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
lxml>=4.9.0 # Faster HTML parsing
# Optional: For advanced features
# python-dotenv>=1.0.0 # For .env file support
# aiohttp>=3.8.0 # For async requests (optional)
The Oxylabs function claims to use a built-in OpenClaw tool but actually returns fabricated mock results. In an agent setting, synthetic data presented as search output can corrupt decision-making, hide failures, and enable silent integrity attacks because consumers may act on nonexistent sources.
The docstring and comments explicitly claim REAL integration while the function only prints a message and returns mock data. Security-wise, deceptive behavior inside an agent skill is risky because it can mislead operators, conceal non-functional or substituted logic, and undermine assurance about what external actions the skill actually performs.
Presenting user-agent rotation as a security/compliance feature is risky because user-agent rotation is commonly associated with anti-detection and can encourage evasive scraping behavior. In the context of a search/scraping skill with lightweight HTTP fallback, this framing may normalize bypassing service restrictions and increase legal, abuse, and platform enforcement risk.
This markdown file contains user-facing instructions and status information exclusively in French, including the final action the user is expected to take. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.
The skill advertises networked search, caching, and local tooling but does not declare any explicit tool scope or permissions boundaries. In agent environments, missing scope declarations can cause overbroad access to env, filesystem, shell, and network capabilities, making review and containment harder if the implementation is later added or changed.
The skill encourages use of external search APIs and scraping paths without clearly warning that user queries may be sent to third-party services. Search queries often contain sensitive business, personal, or investigative terms, so silent transmission can create privacy and compliance exposure even if the search itself is legitimate.
The batch processor reads arbitrary queries from local files and sends them to SearchEngine.search(...), which likely performs remote searches, but the code provides no explicit warning, consent gate, or data classification check before transmitting potentially sensitive query contents off-host. In a batch mode tool, this increases the risk of unintentional disclosure because users may process files containing internal terms, customer data, or confidential investigations at scale.
The skill is marketed as Google Search, but the implementation may return DuckDuckGo, mock Oxylabs data, or other fallback results without clearly informing the caller. This can mislead downstream agents or users into trusting provenance and accuracy that they did not actually receive, which is especially risky in automated workflows that depend on source identity.
The cache stores raw search queries and full results in a local SQLite database by default, creating persistent retention of potentially sensitive user interests, prompts, URLs, or snippets. In shared or multi-tenant environments, this can expose private activity or data to other users, backups, or later compromise.
The cache stores raw search queries and full results persistently in a local SQLite database without any notice, minimization, or protection controls. In an agent context, queries may contain sensitive business, personal, or security-investigation terms, so local persistence increases exposure to other local users, backups, or later compromise.
The code presents the primary path as 'real OpenClaw integration' but actually returns fabricated mock results. This is dangerous because downstream users or agents may trust the output as genuine search data and make decisions based on false information, creating integrity and supply-chain trust risks.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
import requests
url = "https://api.duckduckgo.com/"
params = {
"q": query,
"format": "json",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
import requests
url = "https://api.duckduckgo.com/"
params = {
"q": query,
"format": "json",