Back to skill

Security audit

Twexapi CLI

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Twexapi CLI helper, but it handles high-impact account credentials and includes overbroad request behavior that can expose secrets, so it belongs in Review before installation.

Install only if you are comfortable with this CLI storing Twexapi API keys and Twitter/X session material locally in plaintext and sending authenticated requests on your behalf. Use --dry-run before any write action, avoid saved profiles on shared machines or CI, keep config directories private, do not use untrusted --base-url values, and avoid invoking the generic full-URL request form with credentials configured.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
src/request.js:17
Finding

API Key Disclosure Through Authenticated Requests to Arbitrary URLs

Content
View full analysis
"); await performRequest(state, config, { method: state.method, path: requestPath, body: state.data, }); } export async function runCommand(state, config) { const [command] = state.commandArgs; if (!command) { return false; } if (command.startsWith("/") || /^https?:\/\//i.test(command)) { await handleGenericRequest(state, config, state.commandArgs); return true; } ``` ```js const target = normalizePath(request.path); const url = /^https?:\/\//i.test(target) ? target : `${appState.baseUrl}${target}`; const headers = { Accept: "application/json", ...state.headers, ...request.headers, }; if (appState.apiKey) { headers.Authorization = `Bearer ${appState.apiKey}`; } ``` ```js const response = await fetch(url, { method: request.method, headers, body, }); ``` ### Technical Analysis The generic request interface accepts an absolute HTTP or HTTPS URL. The HTTP layer then adds the configured Twexapi API key to the `Authorization` header without verifying that the destination belongs to Twexapi. Consequently, authentication credentials are sent to any destination supplied as the command argument. Plaintext HTTP URLs are also accepted, allowing the key to be exposed through network interception. This violates credential-origin binding: a credential issued for one service must not be forwarded to an unrelated origin. The same functionality also permits the CLI to make requests to loopback, private-network, or link-local destinations, although exploitation of that request capability depends on where and how the CLI is execut ...[truncated 1304 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/config.js:28
Finding

Plaintext Credential Configuration Is Written Without Explicit Restrictive Permissions

Content
View full analysis
[--cookie | --auth-token ] [--ct0 ]"); } config.profiles[name] = { ...(cookie ? { cookie } : {}), ...(authToken ? { authToken } : {}), ...(ct0 ? { ct0 } : {}), }; if (!config.currentProfile || hasFlag(args, "--use")) { config.currentProfile = name; } await saveConfig(state.configDir, config); ``` ### Technical Analysis The configuration can contain API keys, complete cookie strings, `auth_token` values, and `ct0` values. These credentials are serialized directly into plaintext JSON. Neither `fs.mkdir` nor `fs.writeFile` specifies a restrictive permission mode. The resulting permissions therefore depend on the process umask and any pre-existing directory or file permissions. Under permissive environments, the file may be readable by other local users or processes. The caller can also select a custom configuration directory through `--config-dir` or `TWEXAPI_CONFIG_DIR`, increasing the possibility that secrets are stored in a shared workspace, CI artifact directory, synchronized folder, or source repository. ### Attack Path 1. The victim saves credentials, for example: ```bash twexapi auth profiles add --name founder --cookie "ct0=...; auth_token=..." ``` ...[truncated 1073 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/commands.js:48
Finding

Twitter Authentication Token Is Embedded in the Request URL

Content
View full analysis
[--save-as ] [--ct0 ]"); const saveAs = findOption(args, "--save-as"); const response = await performRequest(state, config, { method: "GET", path: `/twitter/${encodeURIComponent(authToken)}/cookie`, silent: Boolean(saveAs), }); ``` ### Technical Analysis The `auth cookie` command places the Twitter/X `auth_token` directly in a GET request path. Percent encoding only makes a value syntactically safe for a URL; it does not provide confidentiality. URLs are commonly recorded by reverse proxies, API gateways, load balancers, access logs, observability platforms, tracing systems, browser-like tooling, and server error reports. Any component that records the request target may retain the complete token. The destination is also configurable through `--base-url`, `TWEXAPI_BASE_URL`, or a saved app configuration. No HTTPS or trusted-origin validation is applied before transmitting the token. Therefore, an incorrect or attacker-influenced base URL can send the token to an unintended server or over plaintext HTTP. ### Attack Path #### Logging exposure 1. The victim executes: ```bash twexapi auth cookie --auth-token "" --save-as founder ``` 2. The command creates a URL containing the token: ```text /twitter//cookie ``` 3. An intermediary or destination service records the request URL in an access log or trace. 4. A person or system with access to those logs retrieves the token. 5. The token is reused while it remains valid. #### Configured-destination exposure 1. An attacker causes the victim to set or ...[truncated 770 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/help.js (reported line 60)May include surrounding context.

js
Global options should be placed before the command.
  Saved apps store API keys and base URLs.
  Saved profiles store cookies or auth_token values for write actions.
  Get API keys from https://twexapi.io/dashboard.
  Copy the API key from the dashboard and save it with auth apps add.
`);
}

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 72)May include surrounding context.

twexapi auth apps use prod

text

Save a write profile:

```bash
twexapi auth profiles add --name founder --cookie "ct0=...; auth_token=..."

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs use of a network-capable CLI and references environment/config-based credentials, but it does not declare any tool scope such as allowed tools or permissions. That omission weakens least-privilege controls and can let an agent invoke networked operations and access sensitive auth material without explicit policy boundaries.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill normalizes use of saved profiles, persistent config in ~/.twexapi/config.json, and storage of cookies/auth_token/ct0 in plain JSON for later write requests. This creates session persistence and credential-retention risk: tokens may outlive the task, be reused unintentionally, or be exposed to other local users, logs, or subsequent agent runs.

Content

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

md
1. Confirm the CLI is available.
2. Make sure an app config or API key is available for read requests.
3. Make sure a saved profile or explicit cookie is available for write requests.
4. Prefer convenience commands first.
5. Fall back to `twexapi <path>` only when no convenience command fits.
6. Use `--dry-run` before real write actions unless the user explicitly asks to execute them.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The default prompt uses very broad activation language ('Use $twexapi-cli to install, configure, and run twexapi commands...') without clear limits on when the skill should be invoked or what operations require explicit user intent. In a credential-aware CLI skill, this can cause over-invocation and unintended execution paths involving installation, configuration, or authenticated API actions, increasing the risk of unnecessary access to secrets or unreviewed external operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The auth cookie flow sends a highly sensitive auth token to a remote endpoint to derive a cookie, but this file provides no explicit user-facing disclosure or safety gating around that transmission. In a skill context, hidden transmission of reusable account credentials is risky because users may not understand they are exporting credentials off-box to another service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The command persists the retrieved cookie and auth token into configuration, creating a durable local store of credentials without any warning in this code path. Stored session cookies and tokens materially increase compromise impact if the config is later read by another local user, process, backup system, or plugin.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

These commands send tweet text and authentication cookie data in network requests that can create public account actions. The file includes no confirmation prompt, safety notice, or inline disclosure for these externally visible operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code issues authenticated network requests for social actions and reversals using cookie data, but provides no prompt, log, or warning that account state will be changed remotely. These are user-impacting operations and the file itself contains no disclosure text.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code sends a username and resolved authentication cookie in network requests that change the user's follow relationships. There is no confirmation prompt, visible warning, or explanatory comment/docstring informing users that the command will modify their account state.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generic request handler allows arbitrary raw paths or full URLs whenever the first argument starts with '/' or 'http(s)://'. In a skill intended to provide command-scoped twexapi operations, this bypasses the safer command routing and can be abused to reach unintended internal or external endpoints, expanding the attack surface to SSRF-like behavior or unauthorized API use.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · src/help.js (reported line 35)May include surrounding context.

js
Examples:
  twexapi --app prod users elonmusk sama
  twexapi --profile founder tweet create --text "hello world" --media-url "https://example.com/image.jpg"
  twexapi --profile founder tweet like 1900000000000000000
  twexapi --app prod -X POST -d '["1900000000000000000"]' /twitter/tweets/lookup
  twexapi auth apps add --name prod --api-key "twitterx_..."

Static analysis

No suspicious patterns detected.