T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/wspaces_auth.sh:24
- Finding
- Credentials Exposed Through Process Arguments and Plaintext Storage<![CDATA[ ## Vulnerability Details **File Location**: `scripts/wspaces_auth.sh:24-25, 39-51, 59-60, 69-72, 80-81, 93-94`; `SETUP.md:14-30`; `SKILL.md:14-27` **Vulnerability Type**: Sensitive credential exposure **Risk Level**: Medium ### Vulnerable Code The authentication script accepts passwords as command-line arguments and expands passwords and API keys directly into `curl` arguments: ```bash --email) EMAIL="$2"; shift 2 ;; --password) PASSWORD="$2"; shift 2 ;; ``` ```bash register) if [ -z "$EMAIL" ] || [ -z "$PASSWORD" ] || [ -z "$NAME"" ]; then echo "Error: --email, --password, and --name required" exit 1 fi curl -s -X POST "$API_BASE/api/v1/auth/register" \ -H "Content-Type: application/json" \ -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"name\":\"$NAME\"}" | jq . ;; login) if [ -z "$EMAIL" ] || [ -z "$PASSWORD" ]; then echo "Error: --email and --password required" exit 1 fi curl -s -X POST "$API_BASE/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" | jq . ;; ``` Authenticated requests similarly expand the API key into a process argument: ```bash curl -s -X GET "$API_BASE/api/v1/me" \ -H "X-API-Key: $WSPACES_API_KEY" | jq . ``` The setup documentation recommends permanently storing the API key in a plaintext shell startup file: ```bash export WSPACES_API_KEY="wsk_live_xxxx..." ``` ```bash echo 'export WSPACES_API_KEY="wsk_live_xxxx..."' >> ~/.bashrc source ~/.bashrc ``` `SKILL.md` also suggests plaintext `.env` storage: ```text WSPACES_API_KEY=wsk_live_xxxx... ``` ### Technical Analysis Passwords supplied through `--password` are recorded in the invoking shell's command history under common shell configurations. The script then embeds those passwords in the JSON argu ...[truncated 2526 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Stop accepting passwords directly through ordinary command-line arguments. Prompt interactively with silent input, for example using `read -r -s`, or accept the password through a protected file descriptor. 2. Construct request bodies through standard input rather than placing secret-bearing JSON in the `curl` argument vector. For example, generate JSON with `jq -n` and pipe it to `curl --data-binary @-`. 3. Avoid placing API-key headers directly in command-line arguments where the runtime environment exposes process arguments. Use a permission-restricted temporary curl configuration, protected file descriptor, or an equivalent mechanism that does not expose the key through `argv`. 4. Ensure any temporary credential material is created with restrictive permissions, removed through a cleanup trap, and never written to a shared temporary path. 5. Do not recommend storing live credentials in `~/.bashrc`. Prefer an operating-system credential store, CI secret store, or dedicated secrets manager. 6. If a local environment file must be supported, require permissions such as `chmod 600`, explicitly add it to `.gitignore`, and document that it must not be committed, logged, or backed up without encryption. 7. Redact the `apiKey` and `rawKey` fields from normal command output. Provide an explicit secure export mechanism when the user needs to capture a newly issued key. 8. Add documentation warning users that terminal transcripts, debug modes such as `set -x`, CI logs, and agent logs must not contain passwords or raw API keys. ]]>
