Back to skill

Security audit

AIsa Twitter API Command Center

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed Twitter/X relay, but it needs review because its posting/OAuth client prints the AIsa API key and can upload caller-selected local media files.

Review carefully before installing. Only use it with an AIsa key you are willing to expose to local command logs, avoid attaching sensitive local files, and treat posting as a public account action mediated by the AIsa relay. Rotate the key if it has already appeared in agent or CI output.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/twitter_oauth_client.py:337
Finding

API Key Exposed in Command Output

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/twitter_oauth_client.py:415
Finding

Unrestricted Local File Selection for Network Upload

Content
View full analysis
list[Dict[str, Any]]: if not paths: return [] media_files: list[Dict[str, Any]] = [] media_kinds: set[str] = set() seen_paths: set[str] = set() for raw_path in paths: resolved_path = os.path.abspath(os.path.expanduser(raw_path)) normalized_path = os.path.normcase(resolved_path) if normalized_path in seen_paths: continue seen_paths.add(normalized_path) if not os.path.exists(resolved_path): raise RelayConfigError(f"Media file does not exist: {raw_path}") if not os.path.isfile(resolved_path): raise RelayConfigError(f"Media path is not a file: {raw_path}") mime_type = mimetypes.guess_type(resolved_path)[0] or "application/octet-stream" media_kind = mime_type.split("/", 1)[0] if media_kind not in {"image", "video"}: raise RelayConfigError( f"Unsupported media type for {raw_path}: {mime_type}. Only image and video files are supported." ) media_kinds.add(media_kind) with open(resolved_path, "rb") as file_handle: content = file_handle.read() media_files.append( { "field_name": "media_files", "filename": os.path.basename(resolved_path), "content_type": mime_type, "content": content, } ) ``` The resulting data is subsequently transmitted as multipart form data to the fixed AIsa endpoint. ### Technical Analysis The Skill documentation states that only local files explicitly attached by the user should be uploaded. The implementation does not enforce this boundary. It ...[truncated 2160 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the underlying implementation lacks the advertised research, monitoring, search, and watchlist features while still enabling direct posting or media upload, users may invoke the skill under false assumptions and unintentionally authorize content publication to a third party. In a social-media skill, hidden emphasis on posting is more dangerous because it can lead to reputation harm, account misuse, or accidental data sharing despite a seemingly research-oriented description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the underlying implementation lacks the advertised research, monitoring, search, and watchlist features while still enabling direct posting or media upload, users may invoke the skill under false assumptions and unintentionally authorize content publication to a third party. In a social-media skill, hidden emphasis on posting is more dangerous because it can lead to reputation harm, account misuse, or accidental data sharing despite a seemingly research-oriented description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares required environment access and relies on outbound network communication, but it does not explicitly constrain tool scope with permissions or allowed-tools metadata. That omission can cause the host agent to grant broader execution latitude than users expect, increasing the risk of unintended secret access or network actions when invoking the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The skill explicitly sends user requests, OAuth-related data, and potentially attached local media files to a fixed third-party endpoint. External transmission is expected for this kind of integration, but it is still security-relevant because API keys, uploaded content, and account-linked actions leave the local environment and depend on the remote service's trustworthiness and data handling.

Content

Scanner excerpt · SKILL.md (reported line 64)May include surrounding context.

md
- `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

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 86)May include surrounding context.

md
## Guardrails

- Do not ask the user for their Twitter password.
- Do not use cookie-based login or proxy-based login unless the user explicitly asks for legacy behavior.
- Do not default to `--open-browser`; return the authorization link unless the user explicitly wants local browser launch.
- Do not invent remote URLs for attachments; always use the provided local workspace file path with `--media-file`.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The inline documentation repeatedly frames the script as read-only, including usage comments for 'read' and the CLI description. In contrast, _request contains a POST branch that encodes JSON request bodies, which contradicts the stated read-only intent rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The top-level docstring presents this script as a read-only Twitter/X client and specifically describes read operations using GET. However, the shared _request method includes logic to serialize request bodies for POST requests, indicating write-capable plumbing exists despite the read-only positioning. That is a semantic mismatch between the documented scope and implemented behavior.

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 35)May include surrounding context.

python
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) "

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 29)May include surrounding context.

python
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) "

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The post flow transmits tweet text, media, and the AISA API key to a third-party remote service, but the CLI provides no explicit disclosure or confirmation at the point of transmission. In a local automation skill, this can cause users to unknowingly exfiltrate sensitive draft content or local files to an external API, especially when invoked by another agent or workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The authorization command sends a credential-bearing request containing the AISA API key to a remote endpoint to obtain an authorization URL without prominent disclosure to the user. In the context of an OAuth/posting skill, that increases the risk of users authorizing an external relay service without understanding that account-linking metadata and secrets are being shared off-host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring lists an authorize command with an --open-browser option, and the CLI parser also exposes that flag, implying local browser launch support. However, when the flag is used, the code only prints that browser auto-open is disabled and never calls webbrowser.open, which contradicts the documented command behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.