T09 · Insecure Skill Coding Practices
Warning
- Location
- search.py:111
- Finding
- Plaintext Duplication of Sensitive OpenClaw Memory Content<![CDATA[ ## Vulnerability Details **File Location**: `search.py:16-22`, `search.py:36-38`, `search.py:111-127` **Vulnerability Type**: Plaintext sensitive-data storage **Risk Level**: Medium ### Vulnerable Code ```python WORKSPACE = os.path.expanduser("~/.openclaw/workspace") MEMORY_PATHS = [ f"{WORKSPACE}/MEMORY.md", f"{WORKSPACE}/memory/*.md", f"{WORKSPACE}/knowledge/**/*.md", ] INDEX_PATH = os.path.expanduser("~/.openclaw/memory_index.json") ``` ```python try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() except: return [] ``` ```python index = [] for i, chunk in enumerate(all_chunks): try: embedding = get_embedding(chunk['text'][:1000]) # 限制长度 index.append({ 'text': chunk['text'], 'file': chunk['file'], 'start_line': chunk['start_line'], 'end_line': chunk['end_line'], 'embedding': embedding }) if (i + 1) % 10 == 0: print(f"已处理 {i + 1}/{len(all_chunks)}") except Exception as e: print(f"跳过块 {i}: {e}") with open(INDEX_PATH, 'w') as f: json.dump(index, f) ``` ### Technical Analysis The index builder recursively collects OpenClaw memory and knowledge files, reads their complete contents, and stores each plaintext chunk in `~/.openclaw/memory_index.json`. The index therefore duplicates potentially sensitive material rather than storing only embeddings and minimal source references. The file is created using Python's default permissions as constrained by the current process umask. The implementation does not explicitly require restrictive mode `0600`, encrypt the stored content, enforce an allowlist, or remove entries when source files are deleted or changed. Consequently, rebuilding the index creates a consolidated data repository that can remain readable to other local principals depending on system permissions. The recursively indexed `knowledge/**/*.md` scope is also broader th ...[truncated 1225 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not store source plaintext in the index. Store only embeddings, a stable document identifier, line ranges, and the minimum metadata required for retrieval. 2. Read the source snippet on demand after confirming that the current caller is authorized to access the source file. 3. Create the index with explicit owner-only permissions, such as mode `0600`, rather than relying on the ambient umask. 4. Write the index atomically through a securely created temporary file in the destination directory, apply restrictive permissions, and then replace the previous index. 5. Allow users to configure explicit path allowlists and exclusions. Clearly document that `knowledge/**/*.md` is recursively indexed. 6. Remove stale records when files are deleted or changed, and provide a command to securely remove the entire index. 7. Avoid storing absolute paths unless they are necessary; use validated workspace-relative paths instead. 8. Warn users that memory files may contain secrets and recommend excluding credentials or other high-sensitivity data from indexing. ]]>
