Back to skill

Security audit

Twitter Command Center Search Post Interact

Security checks for vulnerabilities and agentic risk

Overview

This skill does the advertised Twitter/X work, but it exposes the user's API key in normal command output and allows sensitive account actions through a relay with weak destination controls.

Review carefully before installing. Use only a low-privilege AIsa key, assume command output may reveal that key until patched, avoid the status command, do not set TWITTER_RELAY_BASE_URL unless you fully trust the endpoint, and confirm exact posts or engagement actions before letting an agent run them.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/twitter_oauth_client.py:44
Finding

Arbitrary Relay Configuration Can Exfiltrate API Credentials and User Content

Content
View full analysis
str: value = base_url.strip().rstrip("/") if not value: raise RelayConfigError("TWITTER_RELAY_BASE_URL is required.") parsed = urllib.parse.urlparse(value) if parsed.scheme not in {"http", "https"} or not parsed.netloc: raise RelayConfigError("TWITTER_RELAY_BASE_URL must be a valid http(s) URL.") return value def load_config(args: argparse.Namespace) -> Dict[str, Any]: base_url = normalize_base_url( get_env("TWITTER_RELAY_BASE_URL", DEFAULT_BASE_URL) ) aisa_api_key = getattr(args, "aisa_api_key", None) or get_env("AISA_API_KEY") timeout = getattr(args, "timeout", None) or int(get_env("TWITTER_RELAY_TIMEOUT", str(DEFAULT_TIMEOUT))) if not aisa_api_key: raise RelayConfigError("AISA_API_KEY is required.") return { "base_url": base_url, "aisa_api_key": aisa_api_key, "timeout": timeout, } ``` ```python def build_auth_headers(aisa_api_key: str, extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]: headers = { "Authorization": f"Bearer {aisa_api_key}", "User-Agent": DEFAULT_CHROME_USER_AGENT, } if extra_headers: headers.update(extra_headers) return headers def send_json_request( url: str, payload: Dict[str, Any], timeout: int, aisa_api_key: str, ) -> Dict[str, Any]: request = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers=build_auth_headers( aisa_api_key, {"Content-Type": "application/json", "Accept": "ap ...[truncated 4235 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/twitter_oauth_client.py:337
Finding

API Key Is Exposed in Command Output and Agent Logs

Content
View full analysis
None: config = load_config(args) payload = {"aisa_api_key": config["aisa_api_key"]} result = send_json_request( f"{config['base_url']}/auth_twitter", payload, timeout=config["timeout"], aisa_api_key=config["aisa_api_key"], ) if result.get("ok") is False: print(json.dumps(result, indent=2, ensure_ascii=False)) sys.exit(1) auth_url = (result.get("data") or {}).get("auth_url") output = { "ok": result.get("code") == 200 and bool(auth_url), "aisa_api_key": config["aisa_api_key"], "authorizati ...[truncated 3641 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented purpose emphasizes Twitter research, search, trends, and monitoring, but the analyzed behavior appears to be primarily a posting/OAuth relay client without those advertised capabilities. This can misroute user requests to a tool that lacks expected safeguards for research use and can encourage unnecessary authorization for functions the user did not actually request.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose emphasizes Twitter research, search, trends, and monitoring, but the analyzed behavior appears to be primarily a posting/OAuth relay client without those advertised capabilities. This can misroute user requests to a tool that lacks expected safeguards for research use and can encourage unnecessary authorization for functions the user did not actually request.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented purpose emphasizes Twitter research, search, trends, and monitoring, but the analyzed behavior appears to be primarily a posting/OAuth relay client without those advertised capabilities. This can misroute user requests to a tool that lacks expected safeguards for research use and can encourage unnecessary authorization for functions the user did not actually request.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction to default all publishes to --type quote directly conflicts with earlier guidance that normal standalone posts should not send relationship fields and that quote mode requires a target tweet URL. In a posting skill, this can cause unintended quoting behavior, malformed requests, or accidental inclusion of external tweet context, leading to incorrect public posts and unsafe autonomous actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The status command returns the active AISA API key in plain JSON, which is a direct secret disclosure. Anyone able to invoke this command or access its output, logs, transcripts, or downstream tool results could reuse the credential to call protected relay/API functionality.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The status command exposes the configured API key without masking or warning, making accidental secret leakage highly likely during normal use. Because this skill supports OAuth-gated engagement actions, the leaked key could enable unauthorized relay access or abuse of privileged posting/interaction workflows.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Printing the configured API key in plain JSON creates a straightforward exfiltration path through terminal history, orchestration logs, agent transcripts, and monitoring systems. The skill context increases severity because users may be encouraged to call 'status' for troubleshooting, turning routine diagnostics into credential exposure.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The authorize and publishing flows include the AISA API key in printed JSON output, causing secret leakage during normal operation rather than only in debug mode. Because these commands are likely to be invoked by automation or an LLM agent, the key may be persisted in chat history, telemetry, CI logs, or tool traces, enabling unauthorized use of the relay service.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares access to an API key and implies networked script execution, but it does not constrain tool scope with explicit permissions or allowed-tools. In an agent environment, that increases the chance the skill is invoked with broader execution/network capabilities than intended, enabling unintended external calls or environment access during normal use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The invocation description is broad enough to match many generic social-media requests, which raises the probability that an agent will select this skill in situations where account-linked network actions are unnecessary. In the context of a Twitter skill with engagement and OAuth implications, over-selection increases the risk of accidental data exposure, unwanted external calls, or unintended account actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The 'When to use' section is ambiguous and lacks trigger constraints or negative examples, so an agent may invoke the skill for loosely related requests. Because this skill can involve authenticated API use and possible account-affecting actions, ambiguous routing guidance makes accidental or unnecessary execution more dangerous than for a purely local read-only utility.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill enables externally visible actions on a real Twitter/X account (likes, follows, unfollows) but does not prominently warn that these actions will be performed on the user's behalf and may affect their public account state. This can lead to unintended social actions, reputational harm, or accidental engagement if the user does not realize the workflow is operational rather than informational.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · references/engage_twitter.md (reported line 64)May include surrounding context.

md
When the user asks to like, unlike, follow, or unfollow on X/Twitter:

1. Do not ask the user for tweet IDs, tweet links, or user IDs.
2. If the user specifies a direct account such as `@elonmusk`, call the `--user` based command.
3. If the user asks for the latest tweet, use `like-latest` or `unlike-latest`.
4. If the user first asked to query tweets, keep the returned `tweets[]` structure in the current conversation context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · references/engage_twitter.md (reported line 76)May include surrounding context.

md
When the user asks to like, unlike, follow, or unfollow on X/Twitter:

1. Do not ask the user for tweet IDs, tweet links, or user IDs.
2. If the user specifies a direct account such as `@elonmusk`, call the `--user` based command.
3. If the user asks for the latest tweet, use `like-latest` or `unlike-latest`.
4. If the user first asked to query tweets, keep the returned `tweets[]` structure in the current conversation context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · references/post_twitter.md (reported line 147)May include surrounding context.

md
When the user asks to like, unlike, follow, or unfollow on X/Twitter:

1. Do not ask the user for tweet IDs, tweet links, or user IDs.
2. If the user specifies a direct account such as `@elonmusk`, call the `--user` based command.
3. If the user asks for the latest tweet, use `like-latest` or `unlike-latest`.
4. If the user first asked to query tweets, keep the returned `tweets[]` structure in the current conversation context.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill lacks a prominent warning that posting to Twitter/X is a public or semi-public action that may be difficult or impossible to fully reverse once published. For an autonomous agent, omission of that warning raises the risk of accidental reputational, privacy, or compliance harm if users do not realize they are authorizing immediate external publication.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file presents itself as a posting-focused skill but contains contradictory instructions that steer the agent toward quote mode by default. This inconsistency increases the chance that the agent performs a different public action than the user intended, which is particularly risky for social-media publishing because actions are externally visible and may be hard to undo.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The attachment flow explains that local workspace files are uploaded to a relay backend and then to Twitter/X, but it does not clearly warn the user that local content will leave the workspace and be transmitted to external services. In an agent context, this can cause users to unknowingly exfiltrate sensitive images, videos, or metadata through an apparently routine posting workflow.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file advertises the client as read-only, but the shared request primitive supports POST and automatically injects the API key into the JSON body. That mismatch is dangerous because downstream code, wrappers, or future subcommands can invoke write-capable endpoints under a misleading safety model, and placing credentials in request bodies increases the chance of accidental exposure via logs, proxies, or server-side request recording.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The inline usage/docs state read-only behavior, while the implementation contains a generic POST path that can send authenticated write requests. In an agent-skill context, this kind of safety-doc mismatch can cause tools, reviewers, or orchestration layers to grant broader trust than warranted, enabling unintended state-changing actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code file sends usernames, tweet IDs, queries, and similar inputs to a third-party service at api.aisa.one via HTTP requests. While the module docstring describes the API client generally, there is no runtime disclosure, confirmation, or explicit user-facing warning that their inputs will be transmitted off-host to an external service.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file is framed as a local engagement relay client, but its documented behavior includes a status pathway that exposes relay configuration details, including credentials. In an agent skill context, such disclosure is especially risky because tool outputs are often surfaced to users, stored in logs, or shared across components.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/twitter_client.py (reported line 36)May include surrounding context.

python
DEFAULT_TIMEOUT = 30
DEFAULT_BASE_URL = "https://api.aisa.one/apis/v1/twitter"
DEFAULT_CHROME_USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/twitter_oauth_client.py (reported line 27)May include surrounding context.

python
DEFAULT_TIMEOUT = 30
DEFAULT_BASE_URL = "https://api.aisa.one/apis/v1/twitter"
DEFAULT_CHROME_USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This code path returns operation results containing the raw AISA API key without masking or warning, which is a direct secret-handling flaw rather than a mere UX issue. In this skill's context, exposing secrets via routine CLI output is especially dangerous because the surrounding agent platform may automatically collect and redistribute tool output.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.