T05 · Unauthorized Access and Privilege Escalation
- Location
run_weekly.py:38- Finding
Default Cross-Container Database Access Violates Least Privilege
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches a trend-reporting purpose, but its default workflow uses high-impact Docker access and other broad side effects without clear upfront user consent.
Review before installing. Run only in a least-privileged environment without Docker daemon access unless you explicitly want it to copy metrics.db from openclaw-gateway-secure. Prefer --no-bridge and --skip-x for a narrower run, inspect or pin dependencies before pip install, and treat generated Markdown/JSON as untrusted because public skill and community content can influence the report.
run_weekly.py:38Default Cross-Container Database Access Violates Least Privilege
script_generator.py:79Indirect Prompt Injection Through Untrusted Registry and Community Content
script_generator.py:229Unescaped External Content Allows Markdown and Link Injection in Reports
SKILL.md:48Runtime Installation of Unpinned Third-Party Dependencies
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
Using an external X/Twitter search path, extracting tweet URLs, invoking an LLM to structure content, and writing weekly signal files is a materially broader workflow than the declared ClawHub trend/script role. This increases attack surface through additional network sources and untrusted content ingestion while concealing the actual operational behavior from users.
The manifest describes a skill focused on ClawHub skills ranking and script generation, but this file is dedicated to collecting GitHub metadata for core OpenClaw repositories such as openclaw/openclaw and openclaw/clawhub. Tracking repo stars, forks, releases, PRs, and commit activity for ecosystem repositories is a materially different function from analyzing trending skills or producing video-script content.
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
def upsert_skills(skills: list[dict]) -> None:
"""Insert or update skill metadata (does not touch metrics_history)."""
with _connect() as conn:
conn.executemany(
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Requires:
- x-search skill at ~/.claude/skills/x-search/scripts/x_search.py
- XAI_API_KEY in env or .env file
- ANTHROPIC_API_KEY in .env (for LLM structuring step)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Requires:
- x-search skill at ~/.claude/skills/x-search/scripts/x_search.py
- XAI_API_KEY in env or .env file
- ANTHROPIC_API_KEY in .env (for LLM structuring step)
"""
The skill declares executable behavior that uses environment variables, filesystem access, network access, and shell commands, but does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens reviewability and can cause the agent to invoke capabilities the user did not clearly consent to, especially since the skill also installs dependencies and writes persistent local data.
When the manifest description omits social-signal capture and project tracking capabilities, users and reviewers lose a reliable summary of what the skill actually does. This is dangerous because manifest metadata is often the first or only trust signal used to decide whether to invoke a skill.
Overly broad trigger phrases can cause accidental invocation of a skill with network, shell, and file-write behavior in response to common user language. In this context, the risk is amplified because the skill performs dependency installation and persistent local writes, so unintended activation can have real side effects.
The skill instructs dependency installation and execution of commands that create a database and output files without prominently warning about those host modifications. That is a real safety issue because users may authorize what sounds like report generation without understanding that packages will be installed and persistent state will be created locally.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
return {"content": "", "author": ""}
url = f"{CLAWHUB_BASE}/api/v1/skills/{slug}"
try:
resp = httpx.get(url, timeout=REQUEST_TIMEOUT, follow_redirects=True,
headers={"Accept": "application/json"})
if resp.status_code != 200:
return {"content": "", "author": ""}
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
# Get default branch
try:
api_resp = httpx.get(
f"https://api.github.com/repos/{owner}/{repo}",
headers={**headers, "Accept": "application/vnd.github+json"},
timeout=REQUEST_TIMEOUT,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Get default branch
try:
api_resp = httpx.get(
f"https://api.github.com/repos/{owner}/{repo}",
headers={**headers, "Accept": "application/vnd.github+json"},
timeout=REQUEST_TIMEOUT,
)
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
for filename in README_CANDIDATES:
url = f"{GITHUB_RAW}/{owner}/{repo}/{branch}/{filename}"
try:
resp = httpx.get(url, headers=headers, timeout=REQUEST_TIMEOUT)
if resp.status_code == 200:
return resp.text[:MAX_CONTENT_CHARS]
except Exception:
The manifest describes a skill focused on tracking trending ClawHub skills and generating weekly YouTube-style ranking scripts. This file instead runs an hourly heartbeat that snapshots the top 500 skills into storage and also captures OpenClaw ecosystem GitHub repository metadata, which is broader operational data collection than the stated weekly ranking/script-generation behavior.
The docstring explicitly claims "Append-only inserts — no dedup destruction of earlier hourly rows," suggesting non-mutating storage behavior. However, the code later calls storage.upsert_skills(skills), which by definition updates existing records and is not purely append-only, creating a direct contradiction between documentation and implementation intent.
The trigger list contains broad phrases such as "skills weekly", "trending skills", and "weekly report" that can overlap with ordinary user intent and cause the skill to activate unexpectedly. Because this skill performs network access and writes persistent data, accidental invocation can lead to unintended external requests and local data collection without the user realizing this specific skill was selected.
The skill explicitly documents persistent SQLite/JSON storage and community research using web searches, but does not present an upfront warning that using it will perform external network access and retain collected data on disk. In context, this increases privacy and transparency risk because a user may ask for trending information and unknowingly trigger collection, storage, and ongoing snapshot accumulation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def _gh_api(endpoint: str) -> dict | list | None:
"""Call GitHub API via gh CLI. Returns parsed JSON or None on error."""
try:
result = subprocess.run(
["gh", "api", endpoint],
capture_output=True, text=True, timeout=15, encoding="utf-8",
)
No suspicious patterns detected.