T09 · Insecure Skill Coding Practices
- Location
skill/context.py:34- Finding
Conversation Content Is Persisted in Plaintext Without Restrictive File Permissions
- Content
View full analysis
Vulnerability Details
File Location:
skill/context.py:34-36, 65-73
Vulnerability Type: Plaintext storage of potentially sensitive conversation data
Risk Level: MediumVulnerable 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.jsonas 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 as0600.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
- A caller creates a conversation and submits a message containing a credential, personal information, or proprietary content.
- The caller invokes
RouterCore.record_message(), which forwards the message toContextManager.add_message(). add_message()stores the first 200 characters of the message without sensitive-data filtering._save()serializes the conversation history to~/.model-router/contexts.jsonin plaintext.- A local process or user able to read that file obtains the retained conversation content.
Impact Assessment
Success ...[truncated 443 chars]
- Remediation
View 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 as0700. - 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.
