T07 · Tool Hijacking and Spoofing
- Location
scripts/web_search.py:64- Finding
Untrusted Out-of-Package Script Execution
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real web search helper, but it should be reviewed because it can silently run a Tavily script from a neighboring package outside its own reviewed files.
Install only if you are comfortable with your search queries going to external search providers and with the skill reading a Tavily API key from your environment or ~/.openclaw/.env. Review or remove the automatic sibling-package Tavily execution path before using it in a sensitive environment, because a compromised neighboring package could run code with the agent's permissions.
scripts/web_search.py:64Untrusted Out-of-Package Script Execution
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
export TAVILY_API_KEY="tvly-xxxx"
TAVILY_API_KEY=tvly-xxxx
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
return key
# Check config file
config_path = os.path.expanduser("~/.openclaw/.env")
if os.path.exists(config_path):
with open(config_path, "r") as f:
for line in f:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
return key
# Check config file
config_path = os.path.expanduser("~/.openclaw/.env")
if os.path.exists(config_path):
with open(config_path, "r") as f:
for line in f:
The skill documents execution of a Python script, use of environment variables, browser/network access, and file-based configuration, but it does not declare any explicit tool scope or permissions boundary. This can lead to over-broad agent authority at runtime, making it easier for the skill to access shell, network, or local resources beyond what a user would reasonably expect.
The trigger list includes broad, common phrases like "search", "look up", and equivalents in Chinese, which can cause the skill to activate in contexts where the user did not intend external web access. In this skill, unintended invocation is more dangerous because activation can result in network requests, browser automation, and possible transmission of sensitive query text to third-party services.
The skill encourages sending user queries to Tavily, Google, Bing, Baidu, DuckDuckGo, and browser automation without clearly warning that query contents may be disclosed to external providers. In a search skill, this omission materially increases privacy risk because users may include proprietary, personal, or regulated information in search terms without realizing it leaves the local environment.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.append("--include-answer")
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
data = json.loads(result.stdout)
data["engine"] = "tavily"
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.tavily.com/search"
payload = {
"api_key": api_key,
"query": query,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"include_answer": include_answer,
}
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
data = response.json()
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
try:
# Use agent-browser to open and snapshot the search results
# Open the search URL
open_result = subprocess.run(
["agent-browser", "open", url],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
}
# Wait for page to load
subprocess.run(
["agent-browser", "wait", "2000"],
capture_output=True,
timeout=10,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
)
# Get snapshot with interactive elements
snapshot_result = subprocess.run(
["agent-browser", "snapshot", "-i", "--json"],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
results = parse_search_results(engine, snapshot_result.stdout, max_results)
# Close browser
subprocess.run(["agent-browser", "close"], capture_output=True, timeout=10)
return {
"query": query,
The manifest describes a web search skill and does mention Tavily API support, so network search behavior is expected. However, this implementation also reads secrets from both process environment and a user-local config file, which is a broader credential-access capability than ordinary search execution and is not explicitly stated in the manifest description.
No suspicious patterns detected.