T09 · Insecure Skill Coding Practices
- Location
- scripts/memory_semantic_consolidate.py:38
- Finding
- Private memory content and API credentials can be transmitted to an arbitrary endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory_semantic_consolidate.py:38-83` **Vulnerability Type**: Arbitrary-endpoint sensitive data disclosure **Risk Level**: High ### Vulnerable Code ```python def _load_llm_config() -> Dict[str, str]: """Load Anthropic API config from openclaw.json tui provider.""" base_url = os.environ.get("ANTHROPIC_BASE_URL", "") api_key = os.environ.get("ANTHROPIC_API_KEY", "") model = os.environ.get("SEMANTIC_LLM_MODEL", "claude-haiku-4-5-20251001") if not base_url or not api_key: try: cfg_path = Path.home() / ".openclaw" / "openclaw.json" cfg = json.loads(cfg_path.read_text("utf-8")) tui = cfg.get("models", {}).get("providers", {}).get("tui", {}) if not base_url: base_url = tui.get("baseUrl", "") if not api_key: api_key = tui.get("apiKey", "") except Exception: pass return {"base_url": base_url.rstrip("/"), "api_key": api_key, "model": model} def _call_anthropic(prompt: str, system: str, cfg: Dict[str, str]) -> Optional[str]: """Call Anthropic Messages API. Returns assistant text or None on failure.""" url = f"{cfg['base_url']}/v1/messages" body = json.dumps({ "model": cfg["model"], "max_tokens": 4096, "system": system, "messages": [{"role": "user", "content": prompt}], }).encode("utf-8") headers = { "Content-Type": "application/json", "x-api-key": cfg["api_key"], "anthropic-version": "2023-06-01", } try: req = Request(url, data=body, headers=headers, method="POST") with urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode("utf-8")) for block in data.get("content", []): if block.get("type") == "text": return block["text"] except Exception as exc: print(f"[semantic] LLM call fa ...[truncated 3601 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require an explicit opt-in before transmitting workspace memories to an external LLM. Default to the local deterministic fallback. 2. Require `https` and reject plaintext HTTP destinations. 3. Maintain an allowlist of approved provider hostnames and ports. Do not accept arbitrary environment-provided endpoints without explicit administrative approval. 4. Use a dedicated, least-privileged API credential for semantic consolidation rather than automatically reusing a general `tui` provider key. 5. Add a security-focused redaction pass before `_build_prompt()`. Remove credentials, authorization headers, tokens, passwords, private keys, email addresses, personal identifiers, and configurable sensitive patterns. 6. Minimize the transmitted fields and provide users with a preview or audit log showing exactly which memory items will leave the host. 7. Document the recipient, retention implications, and data categories transmitted. 8. Fail closed when destination validation fails and use the existing local fallback rather than attempting the request. ]]>
