T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/send_email.py:287
- Finding
- SMTP Credentials Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send_email.py:287-293`; documented usage in `SKILL.md:335-342` **Vulnerability Type**: Sensitive credential exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument('--smtp-server', required=True, help='SMTP server hostname') parser.add_argument('--smtp-port', type=int, required=True, help='SMTP server port') parser.add_argument('--username', required=True, help='SMTP username') parser.add_argument('--password', required=True, help='SMTP password') parser.add_argument('--from-addr', help='Sender email address (default: username)') ``` The documented execution pattern directly places the secret in the command line: ```bash python3 scripts/send_email.py \ --to recipient@example.com \ --subject "Email Subject" \ --content "Email body content" \ --smtp-server smtp.gmail.com \ --smtp-port 587 \ --username your@email.com \ --password your-password-or-app-password ``` ### Technical Analysis The program requires SMTP passwords, authorization codes, or provider API keys through the `--password` command-line argument. Command-line arguments are not an appropriate secret-transport mechanism because they can be exposed through: - Shell history files. - Process inspection utilities and operating-system process metadata. - Command logging, terminal recording, and audit systems. - Agent execution traces or orchestration logs. - Diagnostic output that records complete command invocations. The affected value may be an SMTP authorization code, an account password, or an API key, depending on the selected provider. Although the program does not deliberately print the password, accepting it through `argparse` creates exposure before the application processes it. ### Attack Path 1. A user follows the documented command format and supplies a real SMTP password or API key using `--password`. 2. The shell records the complete comm ...[truncated 831 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove the required `--password` argument. - Obtain the password through `getpass.getpass()` so it is not echoed or stored in shell history. - Support reading the secret from a protected file descriptor, operating-system keyring, or dedicated secret-management service. - If noninteractive use is required, accept the name of a secret or credential source rather than the secret itself. - Avoid environment variables where stronger secret-delivery mechanisms are available, because environment data can also leak through diagnostics and process inspection. - Ensure orchestration and agent logs redact credentials and never emit complete secret-bearing commands. - Update all examples in `SKILL.md` so they do not encourage placing real credentials in command text. - Recommend narrowly scoped, revocable SMTP credentials instead of primary account passwords. ]]>
