T09 · Insecure Skill Coding Practices
- Location
lib/store.py:90- Finding
Plaintext Persistent Session Key Lacks Restrictive File Permissions
- Content
View full analysis
None: """Lock the vault and clear session key.""" self._session_key = None if self.session_file.exists(): self.session_file.unlink() print("🔒 Vault locked") def is_unlocked(self) -> bool: """Check if vault is currently unlocked.""" if self._session_key: return True if self.session_file.exists(): self._session_key = self.session_file.read_bytes() return True return False ``` ### Technical Analysis The derived AES-256 vault key is written directly to `~/.openclaw/vault/session` as plaintext. Unlike the encrypted vault file, the session file is not explicitly assigned mode `0600`. Its effective permissions therefore depend on the process umask. The key remains on disk after the unlocking process terminates and can persist across reboots until `vault lock` is explicitly invoked. Any process or local account able to read this file can decrypt every credential without knowing or brute-forcing the master password. Persisting a raw encryption key is necessary only for the current multi-command session design, not for the core encrypted-storage functionality. The implementation consequently exceeds the minimum exposure required for a memory-only vault session. ### Attack Path 1. The victim executes `vault unlock`. 2. The application derives the AES key and writes it to `~/.openclaw/vault/session`. 3. The victim leaves the vault unlocked or reboots without invoking `vault lock`. 4. A local process or account with permission to read the session file copies its 32-byte contents. 5. The attacker reads `~/.openclaw/vault/vault.enc.json`. ...[truncated 637 chars]- Remediation
View remediation
