T09 · Insecure Skill Coding Practices
- Location
scripts/twitter_oauth_client.py:338- Finding
AISA API Key Disclosed in OAuth and Publishing Command Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill does what it says for Twitter/X posting and engagement, but it unnecessarily exposes the AIsa API key in command output and has weak boundaries around public actions and media uploads.
Review this skill before installing. It requires an AIsa API key and can publish posts, replies, likes, follows, unfollows, and upload media through a remote AIsa service. Avoid using it where command output is logged unless the API-key output issue is fixed, and only pass media paths you explicitly intend to upload.
scripts/twitter_oauth_client.py:338AISA API Key Disclosed in OAuth and Publishing Command Output
scripts/twitter_oauth_client.py:377AISA API Key Redundantly Transmitted in Request Bodies
scripts/twitter_oauth_client.py:410Media Upload Can Read and Transmit Arbitrary Accessible Local Files
There is a material description-behavior mismatch. The declaration emphasizes explicit engagement workflows and approved posting through AIsa, including likes, follows, replies, and OAuth-gated posting. The supplied code chunk only implements read APIs and a CLI for querying Twitter/X data. Its request helper only sends POST generically, but no action-oriented methods or CLI commands use POST, and all exposed endpoints are read endpoints. The code does support the 'read context' portion of the description, but the key declared engagement and posting capabilities are absent, making the declared purpose substantially broader and materially different from the actual behavior.
The code substantially matches part of the description: it supports read context (list-tweets) and engagement actions for likes/follows, including unlike/unfollow variants, all routed through AIsa relay endpoints. However, the declared purpose overstates capabilities by claiming support for replies and OAuth-gated posting/approved posting, neither of which appear anywhere in this code. The code exposes only /like_twitter, /unlike_twitter, /follow_twitter, and /unfollow_twitter endpoints plus tweet listing and status inspection. There is also no explicit campaign workflow logic. Because key declared capabilities are absent from the implementation, the description does not accurately represent what this code chunk actually does.
The declared description promises a broader Twitter/X engagement skill: likes, follows, replies, read context, and approved posting. The supplied code only implements three commands: authorize, post, and status. Posting supports replies and quote-style chaining, plus media upload and local tweet-length splitting, but there is no code for liking tweets, following accounts, or reading Twitter context. OAuth-gated posting is represented, but the overall declared capability set materially exceeds the actual behavior. Therefore this is a description-behavior mismatch.
The client includes the raw AISA API key in printed JSON outputs for post/authorization-related results, which can expose the credential to terminal logs, shell history capture, CI logs, screen recordings, or downstream tooling that stores stdout. Because this key authorizes API actions, disclosure can enable unauthorized use of the linked AIsa account and abuse of posting capabilities.
The skill declares access to an API key and documents use of a fixed remote endpoint, but it does not declare any explicit tool scope or permissions boundary for environment and network use. In an agent setting, that omission reduces transparency and can allow broader-than-expected secret access and outbound requests, which is a real security concern even if the functionality is intended.
The skill explicitly sends API-key-authenticated requests and possibly user-approved media to a third-party endpoint outside the local environment. External transmission is expected for this type of integration, but it still creates real confidentiality and data-handling risk because agent users may not fully appreciate that prompts, account targets, media, and metadata are being sent to a remote service.
- `AISA_API_KEY` is required for AIsa-backed API access.
- Use repo-relative `scripts/` paths from the shipped package.
- Twitter/X reads, OAuth requests, and user-approved media uploads use the fixed AIsa API endpoint `https://api.aisa.one/apis/v1/twitter`.
- Provide only `AISA_API_KEY`; do not use passwords, cookies, or browser credential export.
## Example Requests
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
When the user asks to like, unlike, follow, or unfollow on X/Twitter:
1. Do not ask the user to manually paste tweet links or IDs.
2. If the user first asked to query tweets, keep the returned `tweets[]` structure in the current agent context.
3. Map ordinal follow-up requests to remembered tweet or author context.
4. If multiple user candidates match a natural-language name, stop and ask the user to confirm the account.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
When the user asks to like, unlike, follow, or unfollow on X/Twitter:
1. Do not ask the user to manually paste tweet links or IDs.
2. If the user first asked to query tweets, keep the returned `tweets[]` structure in the current agent context.
3. Map ordinal follow-up requests to remembered tweet or author context.
4. If multiple user candidates match a natural-language name, stop and ask the user to confirm the account.
The module docstring and implemented CLI expose only read-oriented Twitter/X operations such as user info, search, followers, replies, trends, lists, communities, and spaces. There is no code for likes, follows, replies-as-actions, or posting, so the actual behavior of this file is materially narrower than the skill's manifest description.
This Python code file makes outbound network requests to a third-party endpoint and includes user-provided parameters such as usernames, queries, tweet IDs, and community IDs in those requests. Although the module docstring mentions read APIs and bearer authentication, there is no clear user-facing warning at execution time or explicit disclosure that these inputs are sent to an external service.
The command surface created in main() consists entirely of read and discovery commands, and the parser description explicitly says 'Twitter/X read APIs'. That conflicts with the broader manifest promise of likes, follows, replies, and approved posting workflows through AIsa.
The like/unlike paths send tweet engagement requests directly to the remote relay once a tweet ID or latest tweet is resolved, without any explicit warning or confirmation in the client. Because this skill is specifically designed to perform OAuth-gated engagement actions, accidental invocation or malicious upstream instructions can produce unintended public interactions and reputational harm on the user's account.
The follow/unfollow commands trigger real remote social-account actions immediately after argument parsing and user resolution, with no interactive confirmation, dry-run mode, or explicit consent check in this client. In an agent-integrated workflow, ambiguous prompting, tool misuse, or prompt injection in upstream context could cause unintended account actions that affect the user's social graph and reputation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
DEFAULT_TIMEOUT = 30
DEFAULT_BASE_URL = "https://api.aisa.one/apis/v1"
DEFAULT_CHROME_USER_AGENT = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
DEFAULT_TIMEOUT = 30
DEFAULT_BASE_URL = "https://api.aisa.one/apis/v1"
DEFAULT_CHROME_USER_AGENT = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
The post command transmits tweet text, media IDs, and possibly uploaded file contents to the remote AIsa API endpoint. Although network transmission is inherent to posting, this code does not provide a visible runtime disclosure that local text and media files will be sent to an external service, beyond terse argument help strings.
The authorize command constructs a payload containing the AISA API key and posts it to the AIsa authorization endpoint. The file lacks an explicit warning in comments, docstrings, or user-facing output that credentials are being transmitted over the network during authorization.
The module docstring and CLI argument help indicate an authorize flow with an optional --open-browser behavior, suggesting the client can open the authorization URL locally. However, command_authorize only prints a message that browser auto-open is disabled and never calls webbrowser.open, so the documented behavior contradicts the code.
No suspicious patterns detected.