Back to skill

Security audit

X Research

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed read-only X/Twitter research tool, with expected local caching and optional saved reports, but users should be careful with API token storage and linked-page fetching.

Install only if you are comfortable giving the skill an X API bearer token, paying X API usage costs, and storing queries/tweets/watchlist entries locally. Prefer setting X_BEARER_TOKEN directly or through a dedicated secret mechanism instead of a shared global env file, and treat URLs and text from X posts as untrusted evidence before fetching or reusing 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:139
Finding

Unrestricted Retrieval of URLs Controlled by Untrusted X Posts

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
lib/api.ts:16
Finding

Overbroad Reading of a Shared Plaintext Secrets File

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
lib/format.ts:72
Finding

Unescaped Untrusted Post Content in Agent-Consumable Markdown

Content
View full analysis
"); let out = `- **@${t.username}** (${engagement}) [Tweet](${t.tweet_url})\n > ${quoted}`; if (t.urls.length > 0) { out += `\n Links: ${t.urls.map((u) => `[${new URL(u).hostname}](${u})`).join(", ")}`; } return out; } ``` ```ts export function formatResearchMarkdown( query: string, tweets: Tweet[], opts: { themes?: { title: string; tweetIds: string[] }[]; apiCalls?: number; queries?: string[]; } = {} ): string { const date = new Date().toISOString().split("T")[0]; let out = `# X Research: ${query}\n\n`; out += `**Date:** ${date}\n`; out += `**Tweets found:** ${tweets.length}\n\n`; if (opts.themes && opts.themes.length > 0) { for (const theme of opts.themes) { out += `## ${theme.title}\n\n`; const themeTweets = theme.tweetIds .map((id) => tweets.find((t) => t.id === id)) .filter(Boolean) as Tweet[]; out += themeTweets.map(formatTweetMarkdown).join("\n\n"); out += "\n\n"; } } else { // No themes — just list by engagement out += `## Top Results (by engagement)\n\n`; out += tweets .slice(0, 30) .map(formatTweetMarkdown) .join("\n\n"); out += "\n\n"; } out += `---\n\n## Research Metadata\n`; out += `- **Query:** ${query}\n`; out += `- **Date:** ${date}\n`; ``` ### Technical Analysis Post text, usernames, URLs, query strings, and optional theme titles are inserted directly into Markdown. Markdown metacharacters and structural syntax are not escaped. URL schemes ar ...[truncated 1973 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose frames the skill as general X research, but the documented behavior also includes targeted profile lookups, thread/tweet retrieval, persistent watchlist management, and local file persistence. This mismatch can bypass user expectations and policy gating, leading to unanticipated monitoring of accounts or storage of data on disk under the guise of simple research.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

Claude Code

bash
# From your project
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/rohunvora/x-research-skill.git x-research

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

Claude Code

bash
# From your project
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/rohunvora/x-research-skill.git x-research

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README presents generic phrases like "What are people saying about Opus 4.6?" and "Check what @frankdegods posted recently" as natural-language usage, but it does not define clear activation boundaries or exclusions. In a markdown skill description, these broad examples can act as vague triggers because they resemble normal conversational requests and may cause unintended invocation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · README.md (reported line 207)May include surrounding context.

md
## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=rohunvora/x-research-skill&type=Date)](https://star-history.com/#rohunvora/x-research-skill&Date)

## License

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes environment loading (source ~/.config/env/global.env) and performs networked X/Twitter queries, but it does not declare any explicit tool scope or permission boundaries. That makes the skill's effective privileges opaque to the orchestrator and user, increasing the chance of unintended secret exposure or unauthorized external access when the skill is selected.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation triggers are broad enough to match routine conversation like 'what are people saying about' even when the user did not clearly request this specific skill. Over-broad auto-selection can cause unnecessary network access, external data retrieval, and downstream file writes or watchlist use without sufficiently explicit user intent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · lib/api.ts (reported line 8)May include surrounding context.

ts
import { readFileSync } from "fs";

const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min

function getToken(): string {

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/x-api.md (reported line 14)May include surrounding context.

md
import { readFileSync } from "fs";

const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min

function getToken(): string {

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/x-api.md (reported line 130)May include surrounding context.

md
import { readFileSync } from "fs";

const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min

function getToken(): string {

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/x-api.md (reported line 154)May include surrounding context.

md
import { readFileSync } from "fs";

const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min

function getToken(): string {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code accesses sensitive credentials from both environment variables and a local config file without any disclosure, consent flow, or audit signal to the user. In an agent skill setting, hidden secret discovery is risky because operators may not expect the skill to probe the home directory for reusable credentials.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The wrapper falls back to reading a bearer token from ~/.config/env/global.env, which expands credential access beyond the skill's immediate configuration boundary. For an X research skill, silently harvesting secrets from a general-purpose home-directory file is unnecessary and increases the risk of unintended credential use or secret exposure if this code is reused in broader agent contexts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes a general-purpose X/Twitter research agent for searching recent discourse, but this file also creates and maintains a local watchlist database with add/remove/show operations. Persistent account tracking is a broader product capability than the stated search/research role and is not mentioned in the manifest's described use cases.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes a file-writing behavior via --save and gives the destination path, but it presents the behavior as an option without an explicit user warning about local file creation. Because the skill can affect user data/workspace state, the description should disclose that saved output creates persistent files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file instructs users to authenticate with a bearer token taken from an environment variable, but it does not include any warning about handling credentials securely or avoiding exposure in logs, screenshots, or shell history. Because markdown files should warn about behaviors affecting privacy or sensitive data, this is a missing user disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The documentation explicitly directs the agent to fetch third-party URLs extracted from tweets without any safety boundary. In a research agent context, that can cause unreviewed outbound requests to attacker-controlled sites, potentially leaking metadata, triggering retrieval of harmful content, or expanding the trust boundary beyond X unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The skill persists watchlist data to a local JSON file via writeFileSync, and this storage behavior is not disclosed in a comment/docstring at the write site. Although the command names imply watchlist management, users are not explicitly warned that account names and notes will be stored on disk under the skill directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code writes markdown output to ~/clawd/drafts/ when --save is used. While the flag name suggests persistence and the help text mentions the destination, there is no confirmation prompt or pre-write warning immediately before creating the file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest frames the skill as an X research agent used for searching what people are saying and explicitly contrasts it with posting/account management/history access. The profile and tweet commands add direct account/tweet lookup capabilities that are not reflected in the manifest description of scope.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.potential_exfiltration

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
lib/api.ts:13

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
x-search.ts:40

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
lib/api.ts:1