T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/setup_account.py:68
- Finding
- Authentication secrets are exposed through process arguments and standard output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup_account.py:68-104` **Vulnerability Type**: Credential exposure through command-line arguments and unredacted output **Risk Level**: High ### Vulnerable Code ```python def main(): parser = argparse.ArgumentParser(description="Didit account setup") sub = parser.add_subparsers(dest="command", required=True) reg_p = sub.add_parser("register", help="Register a new account") reg_p.add_argument("email", help="Email address") reg_p.add_argument("password", help="Password (min 8 chars, 1 upper, 1 lower, 1 digit, 1 special)") ver_p = sub.add_parser("verify", help="Verify email with OTP code") ver_p.add_argument("email", help="Email used during registration") ver_p.add_argument("code", help="6-character code from email") log_p = sub.add_parser("login", help="Login to existing account") log_p.add_argument("email", help="Account email") log_p.add_argument("password", help="Account password") args = parser.parse_args() if args.command == "register": result = register(args.email, args.password) print(json.dumps(result, indent=2)) print(f"\n--- Check {args.email} for your 6-character verification code ---") elif args.command == "verify": result = verify_email(args.email, args.code) print(json.dumps(result, indent=2)) api_key = result.get("application", {}).get("api_key", "") org_uuid = result.get("organization", {}).get("uuid", "") app_uuid = result.get("application", {}).get("uuid", "") print(f"\n--- Account ready! ---") print(f"API Key: {api_key}") print(f"Org UUID: {org_uuid}") print(f"App UUID: {app_uuid}") print(f"\nSet this in your environment:") print(f' export DIDIT_API_KEY="{api_key}"') elif args.command == "login": result = login(args.email, args.password) print(json.dumps(result, indent=2)) prin ...[truncated 2304 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove password and OTP positional arguments. 2. Read passwords interactively with `getpass.getpass()` so they are not echoed or embedded in ordinary command history. 3. Accept secrets from a protected secret manager or restricted file descriptor for non-interactive automation. 4. Do not print complete authentication responses. Construct an explicit allowlist of non-sensitive fields for display. 5. Redact `api_key`, `access_token`, `refresh_token`, passwords, OTPs, and similar fields recursively before logging. 6. Do not print an `export` command containing the API key. Provide a generic instruction such as `export DIDIT_API_KEY="<stored securely>"`. 7. Ensure CI systems mask known secret values and disable command tracing around authentication. 8. Encourage short-lived, narrowly scoped credentials and document immediate revocation procedures for accidental exposure. ]]>
