Back to skill

Security audit

AI Twitter Daily

Security checks for vulnerabilities and agentic risk

Overview

The skill is a simple report generator, but it sends a user API key and prompt to a third-party LLM endpoint by default and does not actually fetch Twitter/X data itself.

Review before installing. Use only a key intended for the configured endpoint, preferably a narrowly scoped or disposable router-specific key. Do not send a reusable provider credential to cheaprouter.club unless you trust that service. Also understand that this skill appears to generate an LLM-based report rather than independently collecting current Twitter/X posts.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/daily_report.py:7
Finding
Grok API Credential Is Transmitted to a Third-Party Endpoint by Default<![CDATA[ ## Vulnerability Details **File Location**: `scripts/daily_report.py:7-8` and `scripts/daily_report.py:67-83`; documented in `SKILL.md:14-16` and `README.md:7-16` **Vulnerability Type**: Credential exposure through an untrusted configurable API endpoint **Risk Level**: High ### Vulnerable Code ```python API_URL = os.getenv("GROK_API_URL", "https://api.cheaprouter.club/v1/chat/completions") API_KEY = os.getenv("GROK_API_KEY") ``` ```python def query_grok(prompt): headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": MODEL, "messages": [{"role": "user", "content": prompt}], "temperature": 0.7, "stream": True } response = requests.post(API_URL, headers=headers, json=payload, timeout=180, stream=True) ``` The setup documentation reinforces this configuration: ```bash export GROK_API_KEY="your-api-key-here" export GROK_API_URL="https://api.cheaprouter.club/v1/chat/completions" # optional ``` ### Technical Analysis The script describes `GROK_API_KEY` as a Grok API credential but sends it in an HTTP `Authorization: Bearer` header to `api.cheaprouter.club`, an intermediary domain rather than an official provider endpoint. Because this third-party endpoint is the default, users following the documented setup may unknowingly disclose a provider credential to the router. The endpoint can also be replaced through `GROK_API_URL` without any hostname allowlist, trust validation, or warning. Although HTTPS protects the request in transit, it does not protect the credential from the configured endpoint itself. Any server selected through this variable receives both the bearer credential and the complete prompt. ### Attack Path 1. A user follows the project documentation and exports a valid credential as `GROK_API_KEY`. 2. The user runs `python3 scripts/daily_report.py` without overriding `GROK_API_URL`, or runs it in an enviro ...[truncated 1171 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the third-party default with the official provider endpoint appropriate for `GROK_API_KEY`. 2. If third-party routing is intentionally supported, use a router-specific credential rather than instructing users to supply a reusable provider credential. 3. Remove the custom endpoint default and require users to opt in explicitly to third-party routing. 4. Validate `GROK_API_URL` before transmitting credentials: - Require HTTPS. - Parse the URL rather than using string-prefix checks. - Maintain an explicit allowlist of trusted hostnames. - Reject embedded credentials, unexpected ports, redirects to untrusted origins, and malformed hosts. 5. Disable automatic cross-origin redirects or verify the destination after every redirect so that authorization headers cannot reach an unintended host. 6. Display a clear warning and require explicit confirmation before sending a credential to a non-official endpoint. 7. Document the credential trust boundary, expected issuer, required minimum permissions, rotation procedure, and revocation procedure. 8. Recommend narrowly scoped, short-lived credentials and ensure affected users rotate any key previously sent to an endpoint they do not trust. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tainted flow: 'API_URL' from os.getenv (line 7, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"stream": True
    }
    
    response = requests.post(API_URL, headers=headers, json=payload, timeout=180, stream=True)
    
    if response.status_code != 200:
        print(f"HTTP {response.status_code}: {response.text}", file=sys.stderr)
Confidence
96% confidence
Finding
The request destination is taken from an environment variable and used directly in requests.post, while the Authorization header includes the API key. If an attacker can influence GROK_API_URL, they can redirect the bearer token and full prompt contents to an arbitrary host, causing credential exfiltration and unauthorized outbound transmission. In this skill context, that risk is more dangerous because the skill already performs network egress unrelated to direct Twitter access and defaults to a third-party domain.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The skill documentation is written entirely in Chinese and does not provide any language choice, English alternative, or explanation that the skill is intended only for a Chinese-speaking audience. This creates a natural-language policy concern because it imposes a specific language on users without opt-in or documented justification.

External Transmission

Medium
Category
Data Exfiltration
Content
可选配置:
```bash
export GROK_API_URL="https://api.cheaprouter.club/v1/chat/completions"
export GROK_MODEL="grok-4.20-beta"
```
Confidence
89% confidence
Finding
The README suggests sending API requests, potentially including sensitive prompts or credentials-derived authorization headers, to a third-party endpoint at cheaprouter.club instead of an official vendor URL. In the context of an agent skill that processes user requests and may summarize external content, this increases the risk of unintended data disclosure, logging by an untrusted intermediary, or supply-chain style traffic redirection.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill requires environment variables and an external API endpoint but does not declare any explicit tool/permission scope. This creates a mismatch between documented behavior and the platform's security boundary, making it easier for reviewers or users to miss that the skill may access secrets and communicate over the network.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
export GROK_API_KEY="your-api-key-here"
export GROK_API_URL="https://api.cheaprouter.club/v1/chat/completions"  # optional
export GROK_MODEL="grok-4.20-beta"  # optional
```
Confidence
92% confidence
Finding
The skill instructs users to send requests to a third-party API endpoint at api.cheaprouter.club using an API key stored in environment variables. This introduces external data transmission and secret exposure risk, especially because the endpoint is not an official vendor domain and the skill gives no assurance about data handling, logging, or retention.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The documentation specifies a 'Structured Chinese report' as the fixed output format. This is a natural-language locale policy issue because it mandates a specific language without indicating user choice, opt-in, or a justified region-specific requirement.

External Transmission

Medium
Category
Data Exfiltration
Content
import json
import os

API_URL = os.getenv("GROK_API_URL", "https://api.cheaprouter.club/v1/chat/completions")
API_KEY = os.getenv("GROK_API_KEY")
MODEL = os.getenv("GROK_MODEL", "grok-4.20-beta")
Confidence
86% confidence
Finding
The hardcoded default endpoint points to an external third-party domain, expanding the trust boundary and creating a fixed egress path for prompts and credentials. While merely defining a URL is not exploit code, the combination of a credentialed external service and a non-obvious provider is security-significant in this skill context and increases supply-chain and data-exposure risk.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The skill uses an external LLM service and reads an API credential from the environment even though its stated purpose is a Twitter-report workflow. That mismatch increases the chance of unnecessary secret exposure and undisclosed third-party data sharing, especially since the default endpoint is an unrelated external service. In context, the unjustified credentialed dependency broadens the trust boundary without clear user benefit.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest describes generating a report from top AI researchers and companies, which implies obtaining or analyzing actual Twitter/X content. In code, the skill never calls Twitter/X APIs, performs scraping, or ingests tweet data; instead it sends a prompt containing account names to an external chat-completions endpoint and relies on the model to supply the report.

External Transmission

Medium
Category
Data Exfiltration
Content
"stream": True
    }
    
    response = requests.post(API_URL, headers=headers, json=payload, timeout=180, stream=True)
    
    if response.status_code != 200:
        print(f"HTTP {response.status_code}: {response.text}", file=sys.stderr)
Confidence
90% confidence
Finding
This is a real external transmission: the script sends request data and a bearer-authenticated call to a remote API. External transmission is not automatically malicious, but in this case it is security-relevant because the skill does not clearly disclose the egress and sends data to a third-party LLM service outside the apparent core function of directly querying Twitter sources.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script transmits a substantial prompt and account list to an external API without any user-facing disclosure or consent mechanism. Even if the prompt content is not highly sensitive here, undisclosed outbound transmission to a third party is a security and privacy concern because users may reasonably expect a local or first-party operation for a reporting skill.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The embedded prompt explicitly instructs the model to answer in Chinese, and the script does not provide any option for the user to select another language. Under the policy criteria, hard-coding a specific language without opt-in is a natural-language policy violation unless the locale restriction is clearly justified.

Static analysis

No suspicious patterns detected.