T09 · Insecure Skill Coding Practices
- Location
service/config.py:22- Finding
Plaintext administrative and OAuth credentials are stored and exposed without restrictive file permissions
- Content
View full analysis
None: ensure_skill_dirs() INSTALL_INFO_PATH.write_text( json.dumps(data, ensure_ascii=False, indent=2) + '\n', encoding='utf-8', ) ``` ```python def save_json_atomic(path: Path, data: JsonDict) -> None: tmp_path = path.with_suffix(path.suffix + '.tmp') tmp_path.write_text( json.dumps(data, ensure_ascii=False, indent=2) + '\n', encoding='utf-8', ) tmp_path.replace(path) ``` The installation result contains and prints the plaintext password: ```python install_info = { 'ok': True, 'host': args.host, 'port': port, 'username': creds['username'], 'password': creds['password'], # ... } save_install_info(install_info) # ... print(f"Username: {creds['username']}") print(f"Password: {creds['password']}") ``` The resulting permissions depend entirely on the caller's umask. Under a common `0022` umask, newly created files can be readable by other local users. The same issue affects temporary OAuth profile files and other JSON state files created elsewhere through unrestricted `write_text()` calls. Printing the password is useful for first-run access, but it also places the secret in terminal capture, installation logs, automation output, and agent tool output. Persistent plaintext storage is needed only if Basic Authentication remains the design; broad file readability is not necessary for the declared functionality. ### Attack Path 1. ...[truncated 1305 chars]- Remediation
View remediation
