T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/twitter_oauth_client.py:338
- Finding
- API Key Disclosed in Command Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/twitter_oauth_client.py:338-354`, `scripts/twitter_oauth_client.py:470-475`, and `scripts/twitter_oauth_client.py:539-543` **Vulnerability Type**: Sensitive credential exposure through standard output **Risk Level**: High ### Vulnerable Code ```python if result.get("ok") is False or result.get("code") != 200: return { "ok": False, "aisa_api_key": config["aisa_api_key"], "is_thread": should_thread, "total_chunks": len(chunks), "failed_at_chunk": index + 1, "results": publish_results, } latest_tweet_id = extract_tweet_id(result) if not latest_tweet_id: return { "ok": False, "aisa_api_key": config["aisa_api_key"], "is_thread": should_thread, "total_chunks": len(chunks), "failed_at_chunk": index + 1, "error": "Missing tweet_id in relay response.", "results": publish_results, } ``` ```python output = { "ok": result.get("code") == 200 and bool(auth_url), "aisa_api_key": config["aisa_api_key"], "authorization_url": auth_url, "raw_response": result, } print(json.dumps(output, indent=2, ensure_ascii=False)) ``` ```python response = { "ok": True, "relay_base_url": config["base_url"], "aisa_api_key": config["aisa_api_key"], "timeout": config["timeout"], "supported_commands": ["authorize", "post", "status"], "supported_endpoints": ["/twitter/auth_twitter", "/twitter/post_twitter"], ``` ### Technical Analysis The `authorize`, `post`, and `status` workflows include the complete `AISA_API_KEY` in objects serialized to standard output. This is unnecessary for authorization, publishing, status reporting, or error handling. Standard output from an agent skill may be retained in agent transcripts, CI logs, terminal captures, observability platforms, support bundles, or downstream automation. Consequently, a secret initially protected as an environment ...[truncated 1345 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `aisa_api_key` from every command response, success result, and error object. 2. Ensure that `status` reports only whether the credential is configured, for example: ```python "api_key_configured": bool(config.get("aisa_api_key")) ``` 3. If an identifier is operationally necessary, expose only a non-secret server-generated credential ID. Do not print any recoverable portion of the key. 4. Add automated tests asserting that command output never contains the configured key. 5. Apply centralized output redaction before serializing error objects. 6. Review agent transcripts, CI logs, and monitoring records for previous exposure, delete retained copies where possible, and rotate any key that may have been logged. ]]>
