T09 · Insecure Skill Coding Practices
- Location
SKILL.md:139- Finding
Unrestricted Retrieval of URLs Controlled by Untrusted X Posts
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
SKILL.md:139Unrestricted Retrieval of URLs Controlled by Untrusted X Posts
lib/api.ts:16Overbroad Reading of a Shared Plaintext Secrets File
lib/format.ts:72Unescaped Untrusted Post Content in Agent-Consumable Markdown
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.
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.
# From your project
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/rohunvora/x-research-skill.git x-research
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.
# From your project
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/rohunvora/x-research-skill.git x-research
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
## Star History
[](https://star-history.com/#rohunvora/x-research-skill&Date)
## License
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.
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import { readFileSync } from "fs";
const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min
function getToken(): string {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import { readFileSync } from "fs";
const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min
function getToken(): string {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import { readFileSync } from "fs";
const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min
function getToken(): string {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import { readFileSync } from "fs";
const BASE = "https://api.x.com/2";
const RATE_DELAY_MS = 350; // stay under 450 req/15min
function getToken(): string {
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.
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.
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.
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.
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.
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.
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.
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.
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.
Detected: suspicious.env_credential_access, suspicious.potential_exfiltration