Back to skill

Security audit

X Smart Read

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do the X analytics it advertises, but its setup and credential handling create review-worthy security risk.

Review this skill before installing. It is coherent and uses the official X API, but install uv through a safer verified method, consider pinning dependencies or using a lockfile, run setup only in a private terminal, and grant the X app the minimum read/bookmark permissions you actually need.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SETUP.md:9
Finding

Remote Installer Is Downloaded and Executed Without Verification

Content
View full analysis

Vulnerability Details

File Location: SETUP.md:7-10 and SETUP.md:202-205
Vulnerability Type: Remote payload retrieval and immediate shell execution
Risk Level: High

Vulnerable Code

bash
- [uv](https://astral.sh/uv) — Python package runner (handles dependencies automatically)
  ```bash
  curl -LsSf https://astral.sh/uv/install.sh | sh
  ```

The same command is repeated in the troubleshooting instructions:

markdown
### "uv: command not found"
- Install uv: `curl -LsSf https://astral.sh/uv/install.sh | sh`
- Then restart your shell or run `source ~/.bashrc`

Technical Analysis

The instructions pipe an HTTPS response directly into a shell. The retrieved installer is mutable and is neither pinned to a reviewed release nor verified with a cryptographic checksum or signature before execution.

Use of Astral's official domain reduces the likelihood of a malicious payload but does not eliminate the trust risk. Compromise of the distribution service, publishing infrastructure, DNS/TLS path, or installer itself would change the code executed by users without requiring any modification to this repository.

This behavior is not strictly necessary. The project could direct users to a versioned release package and require integrity verification before execution.

Attack Path

  1. An attacker compromises or gains control over the installer hosting or publishing infrastructure, or otherwise alters the response served from https://astral.sh/uv/install.sh.
  2. A user follows the project setup instructions.
  3. curl retrieves the attacker-controlled response.
  4. The pipe sends the response directly to sh without review or integrity validation.
  5. The payload executes with the privileges of the invoking user.
  6. The payload can access files available to that user, including OpenClaw configuration, X credentials, project files, and other user data.

Impact Assessment

Suc ...[truncated 392 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove all curl | sh instructions.

  • Direct users to a specific, versioned uv release rather than a mutable installer endpoint.

  • Require verification against a checksum published through an independent, authenticated release channel.

  • Prefer signed operating-system packages or official package-manager installation methods.

  • If a script-based installation remains necessary, split download and execution into separate steps:

    bash
    curl -fL -o uv-installer.sh https://example.invalid/versioned/uv-installer.sh
    echo "EXPECTED_SHA256  uv-installer.sh" | sha256sum --check -
    less uv-installer.sh
    sh uv-installer.sh
    
  • Pin the URL to an immutable release artifact and document how users can verify its signature.

T08 · Insecure Dependencies

Warning
Location
scripts/x_setup.py:2
Finding

Automatically Installed Dependency Is Not Locked to a Reproducible Version

Content
View full analysis

Vulnerability Details

File Location: scripts/x_setup.py:2-7 and equivalent inline metadata in the other executable scripts; AGENTS.md:16
Vulnerability Type: Unpinned automatically resolved third-party dependency
Risk Level: Medium

Vulnerable Code

python
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "tweepy>=4.14.0",
# ]
# ///

The documented execution model automatically installs dependencies:

markdown
All scripts use `uv run` (auto-installs dependencies). Run from the skill directory.

Technical Analysis

The constraint tweepy>=4.14.0 accepts any future Tweepy release that satisfies the lower bound. The repository contains no reviewed lockfile, exact version pin, or package hash. As a result, two executions at different times may resolve different dependency code.

Tweepy executes in the same Python process as the Skill and receives the user's X API key, API secret, access token, access-token secret, and bearer token. A compromised dependency release would consequently run in a particularly sensitive context.

This finding does not establish that the current Tweepy package is malicious. The vulnerability is the mutable and non-reproducible dependency resolution process.

Attack Path

  1. An attacker compromises the package publisher account, package registry, release pipeline, or a future compatible Tweepy release.
  2. A malicious version satisfying tweepy>=4.14.0 is published.
  3. A user invokes a script with uv run.
  4. uv resolves and installs the malicious compatible version because no lockfile or exact version prevents the update.
  5. The malicious package executes when imported.
  6. During setup or normal operation, it can access X credentials passed into tweepy.Client and any files available to the invoking user.

Impact Assessment

Exploitation can provide arbitrary Python code execution under the user's account. Because ...[truncated 332 chars]

Remediation
View remediation

Remediation Suggestions

  • Commit a reviewed uv.lock file that resolves exact dependency versions.
  • Replace open-ended lower-bound declarations with reviewed, exact versions where inline script dependencies must be used.
  • Use package hashes or signature verification where supported.
  • Apply the same locked dependency policy consistently to every executable script.
  • Update dependencies through an explicit review process that includes changelog inspection, vulnerability scanning, and test execution.
  • Consider centralizing dependencies in a locked project configuration rather than independently resolving inline metadata for each script.
  • Configure automated dependency updates to create reviewable changes rather than silently accepting future releases at runtime.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/x_setup.py:100
Finding

Interactive Credential Entry Echoes Secrets to the Terminal

Content
View full analysis

Vulnerability Details

File Location: scripts/x_setup.py:100-107
Vulnerability Type: Sensitive credential exposure through visible terminal input
Risk Level: Medium

Vulnerable Code

python
else:
    print("No .env credentials found. Enter your X API keys:")
    print("(Get them at https://developer.x.com)")
    print()
    api_key = input("API Key (Consumer Key): ").strip()
    api_secret = input("API Secret (Consumer Secret): ").strip()
    access_token = input("Access Token: ").strip()
    access_secret = input("Access Token Secret: ").strip()
    bearer_token = input("Bearer Token (optional, press Enter to skip): ").strip()

Technical Analysis

Python's input() function echoes typed characters to the terminal. It is unsuitable for API secrets, access-token secrets, and bearer tokens. Credentials may be exposed to nearby observers, screen-sharing participants, terminal session recorders, remote administration logs, or captured demonstration output.

The setup script does not intentionally print the resulting credential values, and the saved configuration is initially assigned mode 0600. Those protections do not address disclosure while credentials are being entered.

Attack Path

  1. A user runs the interactive setup flow because no suitable credentials are found in ~/.openclaw/.env.
  2. The user enters the API key, API secret, access token, access-token secret, and bearer token.
  3. Each value appears visibly in the terminal because input() enables echo.
  4. An observer, screen recorder, terminal logging facility, or shared-session participant captures the displayed values.
  5. The captured credentials are used to authenticate to X within the permissions granted to the associated application and user tokens.

Impact Assessment

Disclosure can permit unauthorized X API access and consumption of the user's paid API credits. Depending on the permissions assigned to the ...[truncated 401 chars]

Remediation
View remediation

Remediation Suggestions

  • Use getpass.getpass() for every secret value:

    python
    from getpass import getpass
    
    api_key = getpass("API Key (Consumer Key): ").strip()
    api_secret = getpass("API Secret (Consumer Secret): ").strip()
    access_token = getpass("Access Token: ").strip()
    access_secret = getpass("Access Token Secret: ").strip()
    bearer_token = getpass("Bearer Token (optional, press Enter to skip): ").strip()
    
  • Consider treating the API key as sensitive as well, even where a provider does not classify it as a standalone secret.

  • Warn users not to run credential setup in recorded, shared, or screen-broadcast terminal sessions.

  • Prefer an operating-system credential store or keyring over long-term plaintext JSON storage when available.

  • Preserve restrictive permissions after every configuration rewrite and verify that both the configuration directory and file are inaccessible to other users.

  • Add tests confirming that secret prompts disable terminal echo and that redacted configuration output never reveals credential material.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (47)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · CONTRIBUTING.md (reported line 33)May include surrounding context.

md
1. Fork the repo
2. Create a feature branch
3. Add your command + update SKILL.md, AGENTS.md, README.md command table
4. Run the testing checklist above
5. Open a PR with a description of what the command does and its API cost

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

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

md
- **Guarded** (default) — warns you and stops when you hit your daily limit
- **Relaxed** — warns you but keeps going
- **Unlimited** — no limits, no warnings

Every command also supports `--dry-run` to preview what it would cost before making any API calls.

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

Piping curl output into sh creates an immediate command-execution chain from untrusted network content to the shell. In the context of a setup guide for a skill that later handles API tokens, compromise here could lead to host takeover and theft of all imported credentials.

Content

Scanner excerpt · SETUP.md (reported line 9)May include surrounding context.

  • uv — Python package runner (handles dependencies automatically)
    bash
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
  • An X (Twitter) account
  • $5 minimum to load API credits (see Step 4)

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 · SETUP.md (reported line 49)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 52)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 55)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 56)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 71)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 72)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 183)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

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 · SETUP.md (reported line 191)May include surrounding context.

md
- **API Key Secret** (also called Consumer Secret) — looks like: `g9NNNTOi...`
4. Save these somewhere safe — you can't see them again

### Access Token & Secret (User Auth)

1. On the same **Keys and tokens** page, scroll to **Authentication Tokens**
2. Under **Access Token and Secret**, click **Generate**

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk’s primary function is narrow: read any tweet or thread and optionally fetch related conversation posts, while storing results locally and enforcing budget checks. This does align with the 'read any tweet/thread' and 'persistent local store and daily budget guards' parts of the description. However, the declared description presents a substantially broader analytics/monitoring capability set—timeline engagement, mentions, follower tracking, bookmarks, and combined briefings—that is not implemented in this code chunk. Because the supplied code does not reflect most of the advertised functionality and instead only covers one sub-feature, the description does not accurately represent the actual behavior of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code is focused narrowly on the user's own timeline/posts and engagement metrics. It does match parts of the description: timeline engagement, persistent local store, and daily budget guards. However, the declared description promises several additional capabilities that are not present in this code chunk, including mentions, follower tracking, reading any tweet/thread, bookmarks, and combined briefings. Displaying bookmark_count as a metric on tweets is not the same as supporting bookmark access. Because the actual implemented functionality is materially narrower than the declared purpose, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad personal X analytics tool with multiple features: timeline engagement, mentions, follower tracking, reading tweets/threads, bookmarks, and combined briefings. The supplied code only implements a narrow subset: profile lookup for self or another user and optional follower-count history tracking for the authenticated user, plus budget/cost handling. Follower tracking and persistent local storage are consistent with the description, but most of the advertised capabilities are absent from this code chunk. That makes the code's actual behavior materially narrower than the declared purpose.

Content

No source excerpt is available for this finding.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
83% confidence
Finding

Offering an unlimited budget mode described as having 'No warnings, no blocks' weakens a safety guard around paid API usage. While not malicious by itself, normalizing the removal of warnings increases the chance of accidental overspend or agent misuse, especially when combined with broad triggers and shell access.

Content

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

md
The user can set a budget enforcement mode via `x_setup.py --budget-mode`:
- **guarded** (default): Warn at 50/80/100%, block at limit
- **relaxed**: Warn at 50/80/100%, never block
- **unlimited**: No warnings, no blocks

### Budget Tiers

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/x-api-quickref.md (reported line 15)May include surrounding context.

md
| Batch Get Tweets | `GET /2/tweets?ids=id1,id2,...` | Bearer/OAuth | ~$0.005 |
| Search Recent | `GET /2/tweets/search/recent` | Bearer | ~$0.005 |
| Create Tweet | `POST /2/tweets` | OAuth 1.0a | Free |
| Delete Tweet | `DELETE /2/tweets/:id` | OAuth 1.0a | Free |
| Get Bookmarks | `GET /2/users/:id/bookmarks` | OAuth 1.0a | ~$0.005 |
| Bookmark Tweet | `POST /2/users/:id/bookmarks` | OAuth 1.0a | Free |
| Remove Bookmark | `DELETE /2/users/:id/bookmarks/:tweet_id` | OAuth 1.0a | Free |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/x-api-quickref.md (reported line 18)May include surrounding context.

md
| Delete Tweet | `DELETE /2/tweets/:id` | OAuth 1.0a | Free |
| Get Bookmarks | `GET /2/users/:id/bookmarks` | OAuth 1.0a | ~$0.005 |
| Bookmark Tweet | `POST /2/users/:id/bookmarks` | OAuth 1.0a | Free |
| Remove Bookmark | `DELETE /2/users/:id/bookmarks/:tweet_id` | OAuth 1.0a | Free |
| Usage Stats | `GET /2/usage/tweets` | Bearer | Free |

## Tweet Fields

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 · references/x-api-quickref.md (reported line 114)May include surrounding context.

md
| Method | When | Keys Needed |
|--------|------|-------------|
| OAuth 1.0a (User Context) | Own tweets, mentions, get_me, posting, bookmarks | API Key + Secret + Access Token + Secret |
| Bearer Token (App Context) | Public user lookup, public tweets, search | Bearer Token only |

OAuth 1.0a is required for `impression_count` on your own tweets and all write actions (posting, bookmarking).

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/x_setup.py (reported line 22)May include surrounding context.

python
sys.path.insert(0, str(Path(__file__).resolve().parent))
from x_common import CONFIG_DIR, CONFIG_PATH, DATA_DIR, USAGE_PATH, VERSION

ENV_PATH = Path.home() / ".openclaw" / ".env"

BUDGET_TIERS = {
    "lite": {"daily_budget": 0.03, "desc": "Morning brief only, ~$0.50/mo"},

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · AGENTS.md (reported line 168)May include surrounding context.

md
BUDGET_MODES = {
    "guarded": "Warn at 50/80/100%, block at limit (default)",
    "relaxed": "Warn at 50/80/100%, never block",
    "unlimited": "No warnings, no blocks",
}

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · scripts/x_setup.py (reported line 33)May include surrounding context.

python
BUDGET_MODES = {
    "guarded": "Warn at 50/80/100%, block at limit (default)",
    "relaxed": "Warn at 50/80/100%, never block",
    "unlimited": "No warnings, no blocks",
}

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SETUP.md (reported line 125)May include surrounding context.

md
def load_env(path: Path) -> dict[str, str]:
    """Parse a simple KEY=VALUE .env file."""
    env = {}
    if not path.exists():
        return env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/x_setup.py (reported line 38)May include surrounding context.

python
def load_env(path: Path) -> dict[str, str]:
    """Parse a simple KEY=VALUE .env file."""
    env = {}
    if not path.exists():
        return env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/x_setup.py (reported line 90)May include surrounding context.

python
def load_env(path: Path) -> dict[str, str]:
    """Parse a simple KEY=VALUE .env file."""
    env = {}
    if not path.exists():
        return env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/x_setup.py (reported line 100)May include surrounding context.

python
def load_env(path: Path) -> dict[str, str]:
    """Parse a simple KEY=VALUE .env file."""
    env = {}
    if not path.exists():
        return env

Static analysis

No suspicious patterns detected.