T09 · Insecure Skill Coding Practices
- Location
emotion_memory.py:14- Finding
Plaintext Persistence of Sensitive Conversation and Emotion Data
- Content
View full analysis
Vulnerability Details
File Location:
emotion_memory.py, lines 14 and 72–75; sensitive record construction occurs at lines 161–169
Vulnerability Type: Plaintext sensitive-data storage with insufficient access-control and retention safeguards
Risk Level: MediumVulnerable Code
python STORAGE_FILE = os.path.expanduser("~/.memory/emotions/history.json")python def save_history(history: List[Dict]): """保存历史情绪记录""" os.makedirs(os.path.dirname(STORAGE_FILE), exist_ok=True) with open(STORAGE_FILE, 'w', encoding='utf-8') as f: json.dump(history, f, ensure_ascii=False, indent=2)python record = { "user_id": user_id, "timestamp": result["timestamp"], "emotion": result["emotion"], "score": result["score"], "keywords": result["keywords"], "context": message[:100], # 记录上下文 "last_care_time": last_care_time }Technical Analysis
Every invocation of
detect_emotionstores a user identifier, inferred emotional state, matched keywords, and up to 100 characters of the user's message. The accumulated records are serialized as unencrypted JSON at a predictable path under the user's home directory.The implementation does not explicitly create the directory with mode
0700or the file with mode0600; effective permissions therefore depend on the process environment and umask. It also provides no retention limit, deletion mechanism, encryption, or option to disable storage of raw conversation context. Because emotional profiles and conversation excerpts can constitute sensitive personal information, these omissions create an avoidable local disclosure risk.Attack Path
- A user or integrating agent invokes
detect_emotionwith a message containing private information. - The function copies the first 100 characters of that message, along with the inferred emotion and user identifier, into a history record.
save_historywrites the entire accumulated history to `~/.memor ...[truncated 1146 chars]
- A user or integrating agent invokes
- Remediation
View remediation
Remediation Suggestions
-
Minimize collected data
- Do not store raw message context by default.
- Persist only fields strictly required for the feature, such as the emotion category and timestamp.
- Make conversation-excerpt storage explicitly opt-in.
-
Enforce restrictive permissions
- Create
~/.memory/emotionswith owner-only mode0700. - Create the history file with mode
0600, rather than relying on the ambient umask. - Verify and correct permissions when loading existing storage.
- Create
-
Protect data at rest
- Where confidentiality is required, encrypt records using credentials managed by an operating-system keychain or equivalent secure storage.
- Do not hardcode encryption keys in the skill.
-
Implement lifecycle controls
- Add a configurable retention period and automatic pruning.
- Provide APIs to inspect, export, and permanently delete stored history.
- Document what is collected, where it is stored, and how long it is retained.
-
Harden file updates
- Write to an owner-only temporary file in the same protected directory.
- Flush and atomically replace the destination to reduce corruption and unsafe partial updates.
- Avoid following unexpected symbolic links where supported, and verify that the storage path is an expected regular file.
-
