Back to skill

Security audit

OpenClaw Encyclopedia

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed OpenClaw documentation helper that writes a local docs-and-notes cache, with one real but bounded cache-fetching weakness users should understand.

Install only if you want a workspace-local OpenClaw knowledge cache. Treat .OpenClaw-Encyclopedia as operational memory: do not put secrets, tokens, private URLs, or confidential access details in it. Use the cache helper only for intended docs.openclaw.ai pages, and be aware that the current fetcher should ideally add redirect validation, response size limits, and content-type checks.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cache_doc.py:137
Finding

Redirect Validation Bypass and Unbounded Remote Content Caching

Content
View full analysis

Vulnerability Details

File Location: scripts/cache_doc.py, lines 137-156
Vulnerability Type: Redirect-based trust-boundary bypass, limited SSRF, cache poisoning, and resource exhaustion
Risk Level: Medium

Vulnerable Code

python
def fetch_html(url: str) -> str:
    req = urllib.request.Request(url, headers={'User-Agent': USER_AGENT})
    with urllib.request.urlopen(req, timeout=20) as resp:
        charset = resp.headers.get_content_charset() or 'utf-8'
        return resp.read().decode(charset, errors='replace')


def main() -> int:
    parser = argparse.ArgumentParser(description=DESCRIPTION)
    parser.add_argument('--url', required=True, help=PATH_HELP)
    parser.add_argument('--root', default=str(default_root()), help=ROOT_HELP)
    args = parser.parse_args()

    parsed = validate_url(args.url)
    root = Path(args.root).expanduser().resolve()
    html_body = fetch_html(args.url)
    extractor = TextExtractor()
    extractor.feed(html_body)

Technical Analysis

validate_url() restricts the initially supplied URL to HTTPS on docs.openclaw.ai. It also rejects user information, explicit ports, direct IP addresses, query strings, fragments, and path traversal. These are appropriate safeguards for the original request.

However, urllib.request.urlopen() follows HTTP redirects automatically. Only the initial URL is validated; neither intermediate redirect targets nor the final response URL are passed through validate_url(). Consequently, an accepted official documentation URL can redirect to a host outside the allowlist, including an attacker-controlled host or a private-network service.

The function also calls resp.read() without a maximum response size and does not validate the response content type. An unintended endpoint can therefore return an excessively large response or arbitrary content. The response is subsequently converted to text and persistently written ...[truncated 2429 chars]

Remediation
View remediation

Remediation Suggestions

  1. Disable automatic redirects and process each redirect explicitly.
  2. Apply validate_url() to every intermediate and final redirect target.
  3. Require every destination to use HTTPS and exactly match the docs.openclaw.ai allowlist.
  4. After opening the response, validate resp.geturl() before reading or caching any content.
  5. Set a small maximum redirect count to prevent redirect loops.
  6. Read the response incrementally and enforce a strict byte limit. Abort the request if the limit is exceeded.
  7. Allow only expected textual media types, such as text/html and optionally text/plain.
  8. Reject unsupported or missing content types unless an explicit, documented exception is required.
  9. Write cache entries atomically through a temporary file that is renamed only after all validation and parsing succeed.
  10. Mark cached text as untrusted external data and ensure Agents do not interpret instructions embedded in documentation pages as authoritative Skill instructions.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to provide OpenClaw guidance, but it also scaffolds workspace directories and manages a local documentation cache, which is operational behavior not obvious from the headline purpose. Hidden or under-disclosed filesystem initialization increases risk because users may invoke the skill for advice while unintentionally allowing environment modification.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill claims to provide OpenClaw guidance, but it also scaffolds workspace directories and manages a local documentation cache, which is operational behavior not obvious from the headline purpose. Hidden or under-disclosed filesystem initialization increases risk because users may invoke the skill for advice while unintentionally allowing environment modification.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill directs use of outbound network access and local file writes via scripts/cache_doc.py and scripts/init_workspace.py, but it declares no explicit tool scope or permission boundaries. That creates an authorization gap where a seemingly advisory/documentation skill can fetch remote content and modify the workspace without transparent restriction, increasing the chance of unintended data exfiltration, supply-chain exposure, or filesystem tampering.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.