T09 · Insecure Skill Coding Practices
Warning
- Location
- skill/context.py:34
- Finding
- Conversation Content Is Persisted in Plaintext Without Restrictive File Permissions## Vulnerability Details **File Location**: `skill/context.py:34-36, 65-73` **Vulnerability Type**: Plaintext storage of potentially sensitive conversation data **Risk Level**: Medium ### Vulnerable Code ```python def _save(self): """Save contexts to disk""" with open(self.contexts_file, "w") as f: json.dump(self.contexts, f, indent=2) ``` ```python ctx["last_model"] = model_used ctx["messages"].append({ "role": role, "content": content[:200], # Truncate for storage "model": model_used, "type": model_type, "time": datetime.now().isoformat(), }) self._save() ``` ### Technical Analysis The context manager records the first 200 characters of each conversation message and writes the resulting data to `~/.model-router/contexts.json` as plaintext JSON. The implementation does not redact credentials or personal information before persistence, encrypt the stored content, request consent for retention, or explicitly enforce a restrictive file mode such as `0600`. Truncation does not provide meaningful protection because API keys, passwords, access tokens, email addresses, and other sensitive values commonly occur within the first 200 characters. Opening the file with mode `"w"` also preserves the permissions of an existing file, including permissions that may allow access by other local users. ### Attack Path 1. A caller creates a conversation and submits a message containing a credential, personal information, or proprietary content. 2. The caller invokes `RouterCore.record_message()`, which forwards the message to `ContextManager.add_message()`. 3. `add_message()` stores the first 200 characters of the message without sensitive-data filtering. 4. `_save()` serializes the conversation history to `~/.model-router/contexts.json` in plaintext. 5. A local process or user able to read that file obtains the retained conversation content. ### Impact Assessment Success ...[truncated 443 chars]
- Remediation
- ## Remediation Suggestions - Disable conversation persistence by default and require explicit user consent before storing message content. - Run sensitive-data detection and redaction before adding messages to the persistent context. - Avoid storing raw message text unless it is necessary; prefer non-sensitive summaries or metadata. - Create the context file atomically with owner-only permissions (`0600`) and ensure the containing directory uses restrictive permissions such as `0700`. - Validate and repair permissions when opening an existing contexts file. - Consider authenticated encryption when conversation content must persist. - Define and enforce retention limits, deletion controls, and maximum storage bounds.
