T09 · Insecure Skill Coding Practices
- Location
scripts/read_credentials.py:80- Finding
Plaintext Credential Disclosure Through Standard Output
- Content
View full analysis
dict: normalized = {} for key, value in data.items(): if key not in ALLOWED_FIELDS: continue if value is None: continue if isinstance(value, str): value = value.strip() if not value: continue normalized[key] = value if "otp_mode" not in normalized: normalized["otp_mode"] = "manual-first" if not any(field in normalized for field in ("email", "username", "phone")): raise SystemExit("missing identifier: provide one of email, username, or phone") if "password" not in normalized: raise SystemExit("missing password") return normalized ``` ```python data = _load_from_file(args.file) if args.file else _load_from_env(args.env) normalized = _normalize(data) json.dump(normalized, sys.stdout, ensure_ascii=True, indent=2, sort_keys=True) ``` The associated documentation encourages storing credentials in reusable plaintext JSON or environment-variable values: ```json { "site": "gmail", "login_url": "https://accounts.google.com/", "email": "user@example.com", "password": "REPLACE_ME", "otp_email": "user@example.com", "otp_mode": "manual-first", "notes": "Use only for inbox triage tasks." } ``` ```bash export GMAIL_AGENT_LOGIN='{"site":"gmail","email":"user@example.com","password":"REPLACE_ME","otp_mode":"manual-first"}' ``` ### Technical Analysis The credential normalizer explicitly requires a password, retains it in the normalized dictionary, and serializes the complete dictionary to standard output without redaction. Consequently, a password supplied through either an explicitly selected file or ...[truncated 1960 chars]- Remediation
View remediation
