T09 · Insecure Skill Coding Practices
- Location
manager.py:10- Finding
Plaintext Storage of Sensitive Contact Data Without Enforced File Permissions
- Content
View full analysis
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: MediumVulnerable 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
View remediation
Remediation Suggestions
- Create the parent data directory with owner-only permissions (
0700) and verify that it is owned by the expected account. - Create the data file with mode
0600rather than relying on the process umask. Check and correct the permissions of existing files before reading or writing them. - Reject symbolic links and unexpected file types. Where supported, use no-follow semantics and verify the opened file descriptor with
fstat. - 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. - Validate the ownership and mode of both the directory and file on every load. Refuse operation when either is writable by unintended users.
- 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.
- Minimize retained personal information and avoid storing optional sensitive fields unless required by the Skill's purpose.
- Create the parent data directory with owner-only permissions (
