Back to skill

Security audit

X Single Tweet + Article

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims at a high level, but it bundles billing authority and broad network fetching in ways users should review before installing.

Review this skill carefully before installing. It is not just a simple X content fetcher: it can charge a billing account, includes an embedded billing key, sends user IDs and requested URLs to external services, and can fetch arbitrary URLs supplied at runtime. Only use it in a constrained environment after the billing credential is removed or rotated, URL validation is added, and all third-party data sharing and pricing are made explicit.

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
scripts/run.js:18
Finding

Hard-Coded Billing API Credential

Content
View full analysis
null); } async function charge() { const r = await fetch(`${BILLING_URL}/charge`, { method: 'POST', headers: { 'content-type': 'application/json', 'x-api-key': API_KEY }, body: JSON.stringify({ user_id: userId, skill_id: SKILL_ID, amount: PRICE }), }).catch(() => null); } ``` ### Technical Analysis The source code contains a live-looking SkillPay API key as the fallback value when `SKILL_BILLING_API_KEY` is not configured. Because the Skill package is distributed to users, anyone who can read the script can recover this credential. The key is subsequently sent in the `x-api-key` header to the configured billing service. Environment-based override support does not protect the embedded fallback secret. The configurable billing URL also means the embedded credential may be transmitted to an operator-controlled endpoint if `SKILLPAY_BILLING_URL` is changed. ### Attack Path 1. An attacker downloads or otherwise reads the Skill package. 2. The attacker extracts the hard-coded `sk_...` credential from `scripts/run.js`. 3. T ...[truncated 985 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.js:61
Finding

Server-Side Request Forgery Through Unrestricted User-Supplied URLs

Content
View full analysis
null); if (!r || !r.ok) return null; const t = await r.text(); if (!t || t.length < 40) return null; return t; } async function fetchViaJina(u) { const j = `https://r.jina.ai/http://${u.replace(/^https?:\/\//, '')}`; const r = await fetch(j).catch(() => null); if (!r || !r.ok) return null; const t = await r.text(); return t && t.length > 40 ? t : null; } // Tweet fallback: const txt = await fetchViaJina(u) || await fetchTextDirect(u); // Article retrieval: async function fetchArticle(u) { const txt = await fetchViaJina(u) || await fetchTextDirect(u); if (!txt) return null; // ... } ``` ### Technical Analysis The values supplied through `--url` and `--article` are not parsed or restricted to approved X domains. Although the documented purpose is to retrieve X tweets and articles, `fetchTextDirect()` passes the untrusted value directly to `fetch()`. The direct request occurs when the Jina request fails or returns an unsuitable response. Consequently, an attacker can cause the runtime to request localhost, private-network services, cloud metadata endpoints, or other hosts reachable from the Skill execution environment. Successful response bodies are included in the command output, up to 12,000 characters for tweet mode or 50,000 characters for article mode. The code also does not validate redirect destinations, so an apparently permitted public URL could potentially redirect to an internal destination if only initial-host validation were added later. ### Attack Path 1. The attacker identifies an internal HTTP endpoint reachable ...[truncated 1242 chars]
Remediation
View remediation

other

Warning
Location
scripts/run.js:68
Finding

Undisclosed Disclosure of Requested Content Identifiers to Third-Party Services

Content
View full analysis
null); if (!r || !r.ok) return null; const t = await r.text(); return t && t.length > 40 ? t : null; } async function fetchTweet(u) { const id = statusId(u); if (id) { const api = await fetch(`https://api.fxtwitter.com/status/${id}`).catch(() => null); // ... } } ``` ### Technical Analysis Tweet status identifiers are submitted to `api.fxtwitter.com`, while complete supplied target URLs are embedded into requests sent to `r.jina.ai`. These services are third parties relative to X and the billing provider. `SKILL.md` describes the Skill as an X content fetcher but does not disclose that requested identifiers or URLs are sent to FxTwitter and Jina AI. Complete URLs can contain query parameters or path components that reveal user interests, private resource identifiers, tracking tokens, or other contextual information. The code always attempts the Jina route before its direct fallback for articles and tweet fallback retrieval. Thus, third-party disclosure is part of the normal retrieval path rather than an exceptional diagnostic operation. ### Attack Path 1. A user invokes the Skill with an X tweet or article URL. 2. For a recognized tweet status, the script sends the status identifier to `api.fxtwitter.com`. 3. If tweet API retrieval does not return usable content, or when an article is requested, the script embeds the supplied URL into a request to `r.jina.ai`. 4. The third-party service receives the identifier or URL and can process or log associated request metadata. 5. If the submitted URL contains sensitive path or que ...[truncated 739 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared behavior does not match the reported implementation: it includes a hardcoded billing API key, undisclosed third-party network access, and pricing behavior that differs from the advertised 0.001 USDT per call. This is dangerous because hidden credentials can be stolen or abused, undisclosed external services expand the data-exposure surface, and misleading billing creates financial and trust risks for users.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --url "https://x.com/user/status/123" --user "user-1"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --url "https://x.com/user/status/123" --user "user-1"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill metadata declares no tool scope or permissions even though the implementation reportedly uses environment access and outbound network calls. This is dangerous because it hides the real execution capabilities from users and reviewers, reducing informed consent and making abuse of secrets or external communications harder to detect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs mandatory billing before attempting the advertised fetch operation, which introduces undisclosed side effects and sends user/account data to a separate payment service unrelated to the core retrieval function. In a skill that is presented as a content fetcher, this hidden charge-first behavior can mislead users and downstream agents into triggering billing unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code contains a hardcoded default billing API key, which is a real secret exposure rather than merely a missing disclosure issue. If this repository or package is shared, anyone can extract the credential and abuse the billing service, potentially causing unauthorized charges, account compromise, or service misuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill embeds payment-link generation and top-up logic that goes beyond simply fetching a tweet or article, expanding the attack surface and creating opportunities for unexpected financial workflows. This is risky because a seemingly simple retrieval tool can redirect users into external payment actions they did not anticipate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The billing requests transmit a user identifier to an external billing endpoint, and the fetch flow also transmits user-supplied targets to third-party services, without any user-facing disclosure in the code path. This creates a privacy and transparency issue because users may not realize their identifiers and requested resources are being shared externally.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/run.js (reported line 72)May include surrounding context.

js
async function fetchTweet(u) {
  const id = statusId(u);
  if (id) {
    const api = await fetch(`https://api.fxtwitter.com/status/${id}`).catch(() => null);
    if (api && api.ok) {
      const d = await api.json().catch(() => null);
      if (d?.tweet?.text) {