T09 · Insecure Skill Coding Practices
- Location
scripts/setup-wizard.py:14- Finding
Credentials Exposed Through Echoing Interactive Prompts
- Content
View full analysis
str: suffix = f" [{default}]" if default else "" value = input(f"{label}{suffix}: ").strip() return value or default ``` The vulnerable helper is used directly for both supported credential types: ```python token = _prompt("PIPEDRIVE_API_TOKEN", os.environ.get("PIPEDRIVE_API_TOKEN", "")) ``` ```python access_token = _prompt("PIPEDRIVE_ACCESS_TOKEN", os.environ.get("PIPEDRIVE_ACCESS_TOKEN", "")) ``` ### Technical Analysis The `_prompt` function uses the ordinary `input()` function for secrets. This causes newly entered API tokens and OAuth access tokens to remain visible while the user types them. More critically, when a credential is already present in the environment, it is passed as `default` and interpolated into the prompt through: ```python suffix = f" [{default}]" if default else "" ``` Consequently, the complete credential is printed to the terminal before the user enters anything. This behavior conflicts with the rule in `SKILL.md` stating that raw tokens must never be printed or echoed. Although the setup wizard legitimately needs a token to validate the Pipedrive connection, displaying that token is unnecessary and exceeds minimum credential-handling requirements. ### Attack Path 1. A valid credential is stored in `PIPEDRIVE_API_TOKEN` or `PIPEDRIVE_ACCESS_TOKEN`. 2. The user or an automation environment runs `scripts/setup-wizard.py` as documented. 3. The corresponding environment value is passed to `_prompt` as its default. 4. `_prompt` embeds the complete token in the visible terminal prompt. 5. The credential is captured through terminal scrollback, session recording, CI logs, screenshots, screen sharing ...[truncated 900 chars]- Remediation
View remediation
str: if existing: reuse = input(f"{label} is already configured. Reuse it? [Y/n]: ").strip().lower() if reuse in {"", "y", "yes"}: return existing return getpass.getpass(f"{label}: ").strip() ``` 2. Never display an existing credential as a prompt default. Indicate only whether it is configured. 3. Avoid logging, printing, or returning raw credentials in success and error messages. 4. Where practical, avoid interactive token entry entirely and require secrets to be supplied through a protected secret manager or environment variable. 5. Add tests that populate the credential environment variables and verify that captured stdout and stderr do not contain their values. 6. Document terminal-recording and process-environment risks for users operating in shared or automated environments. ]]>
