T09 · Insecure Skill Coding Practices
- Location
SKILL.md:32- Finding
Mailbox Credentials Are Collected and Stored in Plaintext
- Content
View full analysis
/config.json` Config template: ```json { "email": "", "password": "", "imap_host": "", "imap_port": 993, "mailbox": "INBOX", "state_file": "~/.openclaw/email-monitor//state.json", "max_emails": 20, "fetch_attachments": false, "attachment_dir": "~/Downloads/email-attachments" } ``` ``` `scripts/fetch_emails.py:99-117` then reads the plaintext secret and uses it to authenticate: ```python parser = argparse.ArgumentParser() parser.add_argument("--config", required=True, help="Path to config JSON file") args = parser.parse_args() with open(args.config) as f: cfg = json.load(f) # Merge with defaults for k, v in DEFAULT_CONFIG.items(): cfg.setdefault(k, v) # Expand ~ in paths cfg["state_file"] = os.path.expanduser(cfg["state_file"]) cfg["attachment_dir"] = os.path.expanduser(cfg["attachment_dir"]) state = load_state(cfg["state_file"]) last_uid = int(state.get("last_uid", 0)) mail = imaplib.IMAP4_SSL(cfg["imap_host"], cfg["imap_port"]) mail.login(cfg["email"], cfg["password"]) ``` ### Technical Analysis The Skill explicitly asks the user to disclose a mailbox credential in a conversation and stores that credential unencrypted in `config.json`. Neither the instructions nor the implementation require the file to be ...[truncated 2257 chars]- Remediation
View remediation
