T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:43
- Finding
- Automatic Plaintext Persistence of Potentially Sensitive User Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 43–69 and 108–116 **Vulnerability Type**: Plaintext sensitive-data storage without explicit consent or retention controls **Risk Level**: Medium ### Vulnerable Code ```python PALACE_PATH = os.path.expanduser("~/.openclaw/pv_palace/") def store_memory(content, importance=5, tags=None): """Store memory in the local palace""" os.makedirs(PALACE_PATH, exist_ok=True) path = os.path.join(PALACE_PATH, "memories.json") data = {"memories": [], "index": {}} if not os.path.exists(path) else json.load(open(path)) mem_id = hashlib.sha256(f"{content}{datetime.now().isoformat()}".encode()).hexdigest()[:12] memory = {"id": mem_id, "content": content, "importance": importance, "tags": tags or [], "created_at": datetime.now().isoformat()} data["memories"].append(memory) for tag in (tags or []): data["index"].setdefault(tag, []).append(mem_id) json.dump(data, open(path, 'w'), ensure_ascii=False, indent=2) return f"✓ Memory stored ({importance}/10)" ``` The documented automatic-storage behavior includes: ```text | User expresses a preference | Automatically call store_memory(content, importance=8, tags=["preference"]) | | Important decision | Automatically call store_memory(decision, importance=9, tags=["decision"]) | | New session starts | Automatically call get_context() to load memory | ``` ### Technical Analysis The skill instructs the agent to automatically retain user preferences, decisions, and other conversational information. The content is serialized directly into `~/.openclaw/pv_palace/memories.json` as plaintext JSON. No explicit user opt-in, sensitivity filtering, retention period, deletion mechanism, encryption, or restrictive file mode is defined. `os.makedirs()` and `open()` rely on the host process's default permission and `umask` configuration, which may not provide the confidentiality expected for persi ...[truncated 1496 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require explicit, informed user consent before persisting any conversational information. 2. Disable automatic storage by default and provide per-item confirmation. 3. Reject secrets, credentials, financial data, health data, and other sensitive categories. 4. Store structured facts rather than unrestricted raw conversation text. 5. Create the storage directory and file with explicit owner-only permissions, such as directory mode `0700` and file mode `0600`. 6. Encrypt persistent memory at rest using a key managed separately from the data file. 7. Add configurable retention limits, automatic expiration, and user-facing list, export, and deletion controls. 8. Use atomic file replacement and locking to prevent corruption and concurrent-write data loss. 9. Clearly disclose the storage path, stored fields, retention period, and cross-session loading behavior. 10. Handle malformed or corrupted JSON safely rather than allowing it to terminate memory operations. ]]>
