T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/ftp_sync.py:65
- Finding
- Plaintext server credentials accepted and documented as command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ftp_sync.py:65-75`; usage examples also appear in `SKILL.md:27-29` and `SKILL.md:42-47` **Vulnerability Type**: Plaintext credential exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```python p_up = subparsers.add_parser("upload", help="上传同步") p_up.add_argument("local", help="本地目录") p_up.add_argument("--host", required=True, help="服务器地址") p_up.add_argument("--user", required=True, help="用户名") p_up.add_argument("--password", help="密码") p_up.add_argument("--remote", required=True, help="远程目录") p_down = subparsers.add_parser("download", help="下载同步") p_down.add_argument("local", help="本地目录") p_down.add_argument("--host", required=True, help="服务器地址") p_down.add_argument("--user", required=True, help="用户名") p_down.add_argument("--password", help="密码") ``` The project documentation actively demonstrates this interface: ```bash python3 scripts/ftp_sync.py upload ./local_folder/ --host 192.168.1.1 --user root --password xxx python3 scripts/ftp_sync.py upload ./dist/ --host example.com --user ftpuser --password pass123 --remote /var/www/html/ python3 scripts/ftp_sync.py upload ./data/ --host example.com --user user --password pass --sync ``` ### Technical Analysis Supplying a secret through a command-line option can expose it outside the intended process. Depending on the operating system and host configuration, command-line arguments may be visible through process inspection facilities, process-monitoring software, audit logs, terminal capture, CI logs, or diagnostic tooling. Interactive shells may also retain the complete command in persistent history. The current implementation parses the password but does not perform network synchronization. This means the credential is exposed without providing the advertised authentication benefit. If synchronization is implemented later without changing this interface, the same weakness will affect functional server ...[truncated 1366 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `--password` command-line option from both upload and download subcommands. 2. Prompt interactively with `getpass.getpass()` when password authentication is explicitly requested: ```python from getpass import getpass password = getpass("Server password: ") ``` 3. Prefer SSH agent authentication, protected private keys, or a platform credential manager over password authentication. 4. If non-interactive operation is necessary, integrate with a secret manager or accept a narrowly scoped environment variable only after documenting its residual exposure risks. Do not print or log its value. 5. Clear references to secrets as soon as practical and ensure exceptions, debug output, and synchronization reports never include credentials. 6. Remove all plaintext `--password` examples from `SKILL.md`. 7. Avoid examples that encourage direct remote login as `root`; document a dedicated, least-privileged synchronization account instead. 8. Add tests confirming that passwords are not present in command-line arguments, logs, generated reports, or exception messages. ]]>
