T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/trakt-api.sh:313
- Finding
- OAuth Access and Refresh Tokens Exposed Through Standard Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/trakt-api.sh`, lines 313–314 **Vulnerability Type**: Sensitive credential exposure through standard output **Risk Level**: Medium ### Vulnerable Code ```bash body=$(jq -nr --arg cid "$TRAKT_CLIENT_ID" --arg cs "$TRAKT_CLIENT_SECRET" --arg code "$device_code" '{code:$code, client_id:$cid, client_secret:$cs}') oauth_post "/oauth/device/token" "$body" | jq ``` ### Technical Analysis The device OAuth token exchange sends the complete response from `/oauth/device/token` through `jq` directly to standard output. A successful Trakt token response can contain sensitive OAuth credentials, including an access token and refresh token. Standard output from an agent Skill may be recorded in conversation transcripts, orchestration logs, command histories, debugging systems, or other output-capture infrastructure. Consequently, printing the complete response can disclose credentials outside the intended secret-storage boundary. This behavior also conflicts with the explicit guardrail in `SKILL.md` stating that API keys and access tokens must never be logged or exposed. ### Attack Path 1. A user initiates the device OAuth flow with the `device-code` command. 2. The user authorizes the device code through Trakt. 3. The Skill invokes `device-token` with the authorized device code. 4. Trakt returns a response containing OAuth credentials. 5. The script prints the entire response to standard output. 6. An actor with access to the agent transcript, execution logs, or captured output retrieves the exposed token. 7. The actor uses the token against Trakt API endpoints permitted by its granted OAuth authorization. No local command execution is required to exploit the disclosure; access to captured Skill output is sufficient. ### Impact Assessment An exposed access token may allow unauthorized access to the associated user's Trakt data within the permissions granted to the OAuth application. If a refresh token is ...[truncated 426 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not print the complete token response through normal Skill output. 2. Parse the response internally and store credentials directly in a secure secret store or permission-restricted configuration mechanism. 3. Return only a non-sensitive status message, such as confirmation that authorization succeeded. 4. If credentials must be written to a local file, create it with restrictive permissions such as mode `0600`, avoid predictable temporary paths, and prevent the contents from entering logs. 5. Redact sensitive response fields before displaying diagnostic output, including: - `access_token` - `refresh_token` - `client_secret` 6. Disable shell tracing around credential-handling operations and ensure the agent or orchestration environment does not capture secret-bearing responses. 7. If manual token display is an unavoidable workflow requirement, require explicit user confirmation, clearly warn that the value is sensitive, and use a secure out-of-band secret-delivery mechanism rather than the ordinary transcript. 8. Revoke and rotate any OAuth credentials that may already have appeared in retained transcripts or logs. ]]>
