T09 · Insecure Skill Coding Practices
- Location
scripts/trakt-api.sh:313- Finding
OAuth Access and Refresh Tokens Exposed Through Standard Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Trakt skill mostly matches its purpose, but its OAuth helper can print account tokens into normal output, so it should be reviewed before installation.
Install only after reviewing the OAuth path. Basic read-only commands using TRAKT_CLIENT_ID and TRAKT_USERNAME are low impact, but avoid the device-token command unless token output is redacted or stored through a secure secret mechanism; rotate any Trakt tokens that may have been printed into logs or transcripts.
scripts/trakt-api.sh:313OAuth Access and Refresh Tokens Exposed Through Standard Output
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
Install on Ubuntu/Debian:
sudo apt-get update && sudo apt-get install -y jq curl
The metadata and description present the skill as a simple read-only Trakt lookup requiring only client ID and username, but the documented behavior also includes OAuth device authorization and token exchange using a client secret. This mismatch can cause users or higher-level agents to supply more sensitive credentials than expected and approve flows with broader security consequences than the advertised purpose.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Guardrails
- Never log or expose API keys or access tokens.
- Only call `https://api.trakt.tv`.
- Read-only endpoints only; playback uses OAuth token read access.
- Device OAuth flow is read-only; do not request write scopes.
The script advertises the ability to exchange a device code for an access token, which is credential acquisition behavior. In the context of a skill marketed primarily for read-only activity checks, this is more dangerous because it introduces auth-token procurement capability that could be repurposed for broader account access.
profile User profile info
playback <type> <start_at> <end_at> Playback progress (requires token)
device-code Start device OAuth (gives user_code)
device-token <device_code> Exchange device code for access token
Environment Variables Required:
TRAKT_CLIENT_ID Your Trakt API client id
Declaring and consuming TRAKT_ACCESS_TOKEN and TRAKT_CLIENT_SECRET means the script is designed to handle sensitive credentials. That is a meaningful security concern in this context because the stated skill purpose does not clearly justify secret processing, increasing the risk of over-privileged deployment and accidental exposure of bearer tokens or client secrets.
TRAKT_USERNAME Your Trakt username or user slug
Optional (for playback):
TRAKT_ACCESS_TOKEN OAuth access token (Bearer)
TRAKT_CLIENT_SECRET OAuth client secret (required for device token exchange)
Examples:
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Install on Ubuntu/Debian:
sudo apt-get update && sudo apt-get install -y jq curl
The README expands the skill from simple read-only querying into OAuth device-flow initiation and token exchange, which materially changes the trust and secret-handling model. Even if the resulting token is intended for read access, documenting credential acquisition workflows in a supposedly read-only skill increases the chance of over-privileged use, user confusion, and unsafe handling of OAuth secrets.
The README states 'read-only endpoints only' while also including device-token exchange operations, which is a misleading security claim. This inconsistency can cause operators to trust the skill more than warranted and provide client secrets or tokens under false assumptions about capability and risk.
The skill exposes shell execution capability through an external script but does not declare any explicit tool scope or allowed-tools boundary. This weakens policy enforcement and reviewability, making it easier for a consuming agent to invoke shell-based behavior without clear restriction, especially in a skill that handles API credentials and OAuth-related flows.
The front matter says the skill requires only a client ID and username, yet the command set includes OAuth device-flow token acquisition. That discrepancy is dangerous because it understates the sensitivity of the skill and can mislead users, reviewers, or orchestrators into exposing secrets or enabling auth flows they did not intend to allow.
Including device authorization and token exchange in a skill whose stated purpose is checking user activity unnecessarily expands the attack surface. Even if the resulting scope is read-only, token acquisition functionality introduces credential-handling paths and phishing-like approval flows that are more sensitive than passive API reads.
The script’s manifest describes a read-only Trakt activity/status skill, but the implementation includes OAuth device-code initiation and token exchange flows. Expanding a supposedly read-only skill to mint access tokens increases privilege and broadens the attack surface, enabling future authenticated API use beyond simple public profile/history reads.
Handling TRAKT_CLIENT_SECRET and performing OAuth token exchange gives this script the ability to process sensitive credentials despite being presented as a read-only status checker. In an agent-skill context, hidden secret-handling is dangerous because it can normalize exposing high-value secrets to code that users and reviewers may assume only performs harmless reads.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
url+="?${params}"
fi
curl -s \
-H "Content-Type: application/json" \
-H "trakt-api-version: 2" \
-H "trakt-api-key: ${TRAKT_CLIENT_ID}" \
The documentation tells the agent not to implement OAuth support unless explicitly requested, but the skill already ships built-in OAuth device-flow commands. This inconsistency can confuse safety logic and make an agent more likely to invoke auth-related actions despite the apparent guardrail.
No suspicious patterns detected.