T09 · Insecure Skill Coding Practices
- Location
scripts/strong_runner.py:92- Finding
Authentication Tokens Exposed Through Standard Output
- Content
View full analysis
Vulnerability Details
File Location:
scripts/strong_runner.py:92-115
Vulnerability Type: Sensitive authentication token disclosure
Risk Level: HighThe
logincommand writes the access token and refresh token directly to standard output. Therefresh_tokencommand also prints the complete refresh response, which is documented as containing replacement access and refresh tokens.python def cmd_login(_args): access_token, refresh_token, user_id = _login() _output({ "accessToken": access_token, "refreshToken": refresh_token, "userId": user_id, }) def cmd_refresh_token(args): access_token, refresh_token, _user_id = _login() resp = _request( "POST", "/auth/login/refresh", headers=_auth_headers(access_token), body={ "accessToken": access_token, "refreshToken": refresh_token, }, ) _output(resp)Technical Analysis
Access and refresh tokens are bearer credentials: possession may be sufficient to authenticate as the user. Printing them to stdout exposes them beyond the runner's in-memory authentication boundary. In an agent environment, stdout commonly becomes tool output and may be retained in conversation context, execution traces, observability systems, or application logs.
This disclosure is unnecessary for normal data-fetching operations because each data command calls
_login()internally and uses the resulting access token without requiring manual token management. The implementation therefore grants token visibility to the caller even though the declared workflow does not require that privilege.The issue also conflicts with
SKILL.md, which says that raw tokens must never be exposed to the user.Attack Path
- A user or agent invokes
python3 scripts/strong_runner.py loginorrefresh_token. - The runner authenticates using `STRONG_USERNA ...[truncated 1147 chars]
- A user or agent invokes
- Remediation
View remediation
Remediation Suggestions
- Remove or disable the public
loginandrefresh_tokensubcommands when the runner is used through an agent. - Keep access and refresh tokens entirely in memory and return only a non-sensitive success result, such as the authenticated user ID.
- If direct token retrieval is essential for a separate administrative use case, place it behind an explicit high-friction opt-in option and display a security warning. Do not enable that option in agent-driven workflows.
- Redact authentication fields recursively before serializing any authentication response:
accessTokenrefreshTokenAuthorization- equivalent case or naming variants
- Ensure logging and error-handling layers never record request headers, login bodies, passwords, or token-bearing responses.
- Revoke tokens that may already have been captured and review agent, terminal, CI, and observability logs for prior exposure.
- Add automated tests asserting that stdout and stderr never contain raw access tokens, refresh tokens, passwords, or authorization headers.
- Remove or disable the public
