T09 · Insecure Skill Coding Practices
Warning
- Location
- manager.py:10
- Finding
- Plaintext Storage of Sensitive Contact Data Without Enforced File Permissions## Vulnerability Details **File Location**: `manager.py:10, 17-19, 22-25, 59-68` **Vulnerability Type**: Plaintext sensitive-data storage with insufficient local access controls **Risk Level**: Medium ### Vulnerable Code ```python DATA_FILE = Path("/Users/aibin/.openclaw/workspace/diankeyuan_contacts.json") ``` ```python def load_data(): """加载数据""" if not DATA_FILE.exists(): return {"meta": {"version": "1.0.0", "totalMembers": 0}, "departments": {}, "quickSearch": {}} with open(DATA_FILE, 'r', encoding='utf-8') as f: return json.load(f) def save_data(data): """保存数据""" data["meta"]["updatedAt"] = datetime.now().strftime("%Y-%m-%d") with open(DATA_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) ``` ```python member = { "name": name, "role": role, "office": office, "phone": "", "email": "", "wechat": "", "addedAt": datetime.now().strftime("%Y-%m-%d"), "updatedAt": datetime.now().strftime("%Y-%m-%d"), "notes": notes } ``` ### Technical Analysis The application stores personnel records in an unencrypted JSON file at a fixed, documented path. The data model can contain names, roles, office locations, telephone numbers, email addresses, WeChat identifiers, and free-form notes. The application opens the file using ordinary Python file operations but does not enforce restrictive permissions, verify file ownership, reject symbolic links, or validate the security of an existing file. The resulting permissions therefore depend on the process umask and the state of any pre-existing path. If the file is readable or writable by unintended local principals, sensitive contact data can be disclosed or modified. The fixed path is also disclosed in `SKILL.md:48`, making the storage location easy to identify. The code does not transmit this information over a network, and exploitati ...[truncated 1490 chars]
- Remediation
- ## Remediation Suggestions 1. Create the parent data directory with owner-only permissions (`0700`) and verify that it is owned by the expected account. 2. Create the data file with mode `0600` rather than relying on the process umask. Check and correct the permissions of existing files before reading or writing them. 3. Reject symbolic links and unexpected file types. Where supported, use no-follow semantics and verify the opened file descriptor with `fstat`. 4. Write updates atomically to a securely created temporary file in the same protected directory, set its mode to `0600`, flush and synchronize it, and then replace the destination. 5. Validate the ownership and mode of both the directory and file on every load. Refuse operation when either is writable by unintended users. 6. Consider field-level or file-level encryption for phone numbers, email addresses, WeChat identifiers, and sensitive notes. Keep encryption keys outside the data file and restrict access to them. 7. Minimize retained personal information and avoid storing optional sensitive fields unless required by the Skill's purpose.
