Back to skill

Security audit

X-CLI Toolkit

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently provides broad X/Twitter automation, but it asks users to expose account credentials to an AI agent or plaintext files and can perform sensitive account actions with limited safeguards.

Review before installing. Do not paste your X/Twitter password into an agent chat, shell command, or plaintext config file. Prefer a dedicated low-risk account, imported cookies with restrictive local permissions, an isolated virtual environment, and explicit manual confirmation before any posting, DM, deletion, follow/block/mute, list, poll, or scheduling command. Treat cookies.json and config.json as secrets and avoid using this with accounts whose private messages or public reputation would be costly to lose.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
README.md:39
Finding
Plaintext X/Twitter credentials exposed through agent conversations, command-line arguments, and configuration files<![CDATA[ ## Vulnerability Details **File Location**: `README.md:39-44`, `README.md:52-69`, `config.example.json:1-8`, `scripts/x_auth.py:58-84`, `scripts/x_auth.py:96-101`, `scripts/x_utils.py:26-44` **Vulnerability Type**: Plaintext credential handling and insecure secret storage **Risk Level**: High ### Vulnerable Code and Documentation `README.md:39-44` instructs users to disclose their account password directly to an AI agent: ```markdown ### 🤖 Or Let Your AI Agent Do It If you're using an AI agent (OpenClaw, Claude Code, etc.), just say: > "Install x-cli from https://github.com/ignsoftwarellc/x-cli — my X username is **your_username**, password is **your_password**." ``` `README.md:52-69` recommends passing the password on the command line or storing it in plaintext configuration: ```markdown ### Option 1: Login with credentials ```bash python scripts/x_auth.py login --username your_user --password your_pass ``` ### Option 2: Use existing cookies If you already have a `cookies.json` file (e.g. from a browser export), place it in the project root. ### Option 3: Set credentials in config.json ```json { "x_username": "your_username", "x_email": "your_email@example.com", "x_password": "your_password", "cookies_file": "cookies.json", "proxy": null, "language": "en-US" } ``` ``` `config.example.json:1-8` establishes plaintext password storage as a supported default configuration pattern: ```json { "cookies_file": "cookies.json", "proxy": null, "x_username": "", "x_email": "", "x_password": "", "language": "en-US" } ``` `scripts/x_auth.py:58-84` reads the password from either a command-line argument or plaintext configuration and then saves authenticated cookies: ```python async def cmd_login(args): config = load_config() username = args.username or config.get("x_username") password = args.password or config.get("x_password") email = args.email or config.get("x_email", username) if not usern ...[truncated 4567 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all instructions asking users to submit passwords in AI-agent conversations. 2. Remove or deprecate the `--password` command-line argument. 3. If password authentication must remain available, acquire the password interactively with Python's `getpass.getpass()` so it is not echoed or placed in shell history. 4. Prefer a browser-assisted authorization flow, OAuth, or user-provided cookies over persistent account-password storage. 5. Do not support `x_password` in `config.json`. If unattended authentication is essential, integrate with an operating-system credential store or a dedicated secret manager. 6. Create cookie files with owner-only permissions and verify permissions after `twikit` writes them: ```python cookies_path.chmod(0o600) ``` 7. Validate that the configured cookie path resolves to an intended private location and does not traverse outside the approved data directory. 8. Add `config.json`, `cookies.json`, and equivalent secret files to `.gitignore`. 9. Document that agent transcripts, execution traces, shell history, and backups must never contain credentials. 10. Recommend revoking sessions and changing the account password if credentials were previously supplied through the documented insecure methods. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Unbounded and unhashed third-party dependency permits unreviewed future package releases<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:1`, `SKILL.md:14-17` **Vulnerability Type**: Unpinned dependency and missing package integrity verification **Risk Level**: Medium ### Vulnerable Code and Documentation `scripts/requirements.txt:1` allows any current or future release at or above version 2.0.0: ```text twikit>=2.0.0 ``` `SKILL.md:14-17` directs installation of that unconstrained dependency set: ```bash pip install -r scripts/requirements.txt cp config.example.json config.json # Set cookies_file path or credentials in config.json ``` ### Technical Analysis The lower-bound-only specifier `twikit>=2.0.0` does not identify a reviewed release. A fresh installation can therefore resolve to a substantially newer package than the version used during this audit. No lock file, transitive dependency pinning, or package hashes are present. This risk is particularly significant because `twikit` operates inside the same Python process as the Skill and receives: - X usernames, email addresses, and passwords - Authenticated session cookies - Private DM and timeline data - Content intended for publication - Local media file paths and contents selected for upload A malicious or compromised future package release would execute with the privileges of the user running `pip` or the scripts. This does not prove that the current `twikit` package is malicious; it means the project cannot ensure that future installations use the reviewed dependency code. ### Attack Path 1. An attacker compromises the upstream package account, publishing pipeline, or one of its permitted dependencies and publishes a malicious version satisfying `>=2.0.0`. 2. A user follows the Skill installation instructions at a later date. 3. `pip` resolves the malicious version because no maximum version, exact version, lock, or hash prevents it. 4. Malicious installation-time or runtime package code executes with the installing user's privileges. 5. The compro ...[truncated 968 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `twikit` to an exact version that has been reviewed and tested: ```text twikit==<reviewed-version> ``` 2. Generate a lock file that pins all transitive dependencies. 3. Record package hashes and install with hash enforcement, for example: ```bash python -m pip install --require-hashes -r requirements.lock ``` 4. Review dependency updates before changing the lock file, especially authentication, HTTP, and serialization dependencies. 5. Use automated dependency vulnerability and provenance scanning in CI. 6. Install the Skill in a dedicated virtual environment under a non-privileged operating-system account. 7. Never run the documented dependency installation command with root or administrator privileges. 8. Consider reproducible-build controls and an internally approved package mirror for deployments handling high-value accounts. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Missing User Warnings

High
Confidence
99% confidence
Finding
The README explicitly tells users to give their X username and password to an AI agent for automated installation and authentication. This is dangerous because it normalizes secret disclosure to an autonomous tool that may log, echo, persist, or misuse credentials, and there is no warning about privacy, retention, or scope of access.

Ssd 3

High
Confidence
99% confidence
Finding
Telling users to hand account credentials to an AI agent is a direct secret-exposure anti-pattern. The context makes this more dangerous because the skill is specifically designed for broad authenticated access to a social-media account, including posting and DMs, so compromised credentials enable both privacy loss and account takeover-like abuse.

Missing User Warnings

High
Confidence
99% confidence
Finding
The documentation recommends storing live X credentials directly in config.json in plaintext without any warning or compensating control. Plaintext secret storage materially increases the chance of credential theft through source control exposure, backups, logs, shared workspaces, or other local compromise.

Ssd 3

High
Confidence
99% confidence
Finding
The README recommends storing live credentials in plaintext in config.json, which is a well-known insecure secret-management practice. In a developer/agent workflow, config files are especially likely to be copied, committed, backed up, or inspected by other tools, turning a local convenience into a persistent credential leak risk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a broad, full-featured X/Twitter toolkit covering many user actions. The supplied code chunk is limited to auth management: checking for cookies/proxy/username configuration, performing login via twikit, saving cookies, and showing the authenticated account. Cookie auth and proxy support do align with part of the description, but the primary purpose of this chunk is authentication only, not the broader toolkit functionality claimed. Therefore, the description does not accurately represent what this specific code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The supplied code is narrowly focused on read operations and user search. It does not implement posting, likes/retweets/replies creation, DMs, list management, poll features, or trend retrieval. Therefore the declared description overstates the functionality represented by this code chunk. While the description may describe a larger toolkit, this specific code does not accurately match the full-featured claim; its actual purpose is a read-only CLI for X/Twitter content plus user search.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill exposes impactful actions such as follow/unfollow, mute, block, delete, and other account-modifying operations without an accompanying warning about irreversible or reputation-affecting consequences. In an agent-operated environment, these actions can be triggered accidentally, by prompt injection, or through user misunderstanding, causing account damage or unintended public activity.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README advertises DM send/read capability without clearly warning that the skill can access and transmit private communications. In an agent context, this expands sensitivity significantly because private messages may be ingested, summarized, stored, or acted on by automation without the user appreciating the privacy implications.

Session Persistence

Medium
Category
Rogue Agent
Content
# Schedule a tweet (unix timestamp)
python scripts/x_extra.py schedule 1740000000 "Scheduled tweet!"

# Create a poll
python scripts/x_extra.py poll "Option A" "Option B" "Option C" --duration 1440

# Lists: create, manage, read
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.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill exposes many state-changing and potentially destructive account actions—DMs, follow/unfollow, block/unblock, delete tweet, retweet, bookmark, list changes, poll creation, scheduled posting—while only warning users to confirm before posting tweets. In an agent context, insufficient warnings and confirmation requirements can lead to unintended account actions, privacy breaches, reputational harm, or irreversible content deletion if the agent invokes these commands autonomously or on ambiguous instructions.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The inbox command prints direct-message contents and sender identifiers directly to stdout with no privacy warning, redaction, or confirmation step. Because DMs are inherently sensitive, this increases the risk of accidental exposure through shared terminals, shell history capture, logging systems, screen recording, or CI/automation environments where command output may be retained.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The delete command performs an irreversible account action immediately based solely on command-line input, with no confirmation prompt, dry-run mode, or safeguard against accidental invocation. In a skill designed to automate X/Twitter actions using authenticated cookies, this increases the chance of unintended content deletion from user error, script misuse, or prompt/agent mistakes.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The code defaults the client locale to `en-US` when no language is provided, which imposes a specific language/locale choice. This is a natural-language policy concern because the file does not offer an explicit user opt-in before selecting that locale by default.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code accesses sensitive credentials from configuration and transmits them during `client.login(...)`. While the module docstring mentions client initialization, there is no confirmation prompt, warning comment, or user-facing disclosure here about handling credentials or performing a network login.

Unpinned Dependencies

Low
Category
Supply Chain
Content
twikit>=2.0.0
Confidence
91% confidence
Finding
The dependency is specified with a lower-bound only (`twikit>=2.0.0`), which allows future unreviewed versions to be installed. That creates supply-chain risk because a breaking, vulnerable, or malicious upstream release could be pulled into the skill without notice, especially significant here because the package is used for X/Twitter automation and may handle cookies, DMs, posting actions, and network access.

Static analysis

No suspicious patterns detected.