T01 · Skill Instruction Hijacking
- Location
scripts/generate_post.py:42- Finding
Untrusted X Post Content Is Embedded Verbatim into an LLM Instruction Prompt
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is transparent about generating X posts in a matched voice, but it needs Review because it can imitate arbitrary accounts without consent safeguards and has local data-handling risks.
Install only if you intend to use it for your own account or an account whose owner has authorized voice matching. Treat generated posts as drafts that should be labeled or reviewed before use, avoid targeting private individuals or misleading audiences, and be aware that profile data and sample posts may be written to local files and printed in terminal output.
scripts/generate_post.py:42Untrusted X Post Content Is Embedded Verbatim into an LLM Instruction Prompt
scripts/generate_post.py:20Predictable Shared Temporary Profile Path Allows Symlink-Based File Overwrite
The prompt explicitly directs the model to generate posts that 'EXACTLY match' a real account and would make others think that account wrote them. In the context of a voice-matching X/Twitter skill, this is an impersonation-enabling capability that can facilitate deception, fraud, reputational harm, or coordinated social engineering.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
Generate posts that would make someone think "{profile['account']} definitely wrote this."
"""
return prompt
def generate_via_llm(prompt: str) -> List[Dict[str, Any]]:
"""
The script prints the full generation prompt to stdout, which includes detailed voice-profile data, sample tweets, signature phrases, and account identifiers. This creates a prompt/data exfiltration risk through logs, terminals, wrappers, or downstream tooling, especially because the prompt contains profile-derived content intended to mimic a real account.
# Build prompt
prompt = build_generation_prompt(profile, args.topic, args.type)
# Output prompt (for Dale to use)
print("\n" + "="*80)
print("GENERATION PROMPT FOR LLM:")
print("="*80)
The skill invokes shell commands and references reading and writing local files, but it declares no explicit tool or permission scope. This increases the risk that an agent executes broader-than-expected filesystem or shell actions without clear user visibility or policy enforcement.
The skill is explicitly designed to analyze another person's X account and generate posts that imitate their voice, yet it provides no warning about consent, impersonation, or privacy risks. In context, this makes social-engineering, deceptive content generation, and misuse of scraped public content more likely, especially when used on third-party accounts rather than the user's own account.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
raise FileNotFoundError("Bird CLI not found at /data/workspace/bird.sh")
cmd = [str(bird_path), "user-tweets", username, "-n", str(count)]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"Bird CLI failed: {result.stderr}")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
else:
print(f"Fetching {args.tweets} tweets from {username}...", file=sys.stderr)
tweets = parse_bird_output(
subprocess.run(
["/data/workspace/bird.sh", "user-tweets", username, "-n", str(args.tweets)],
capture_output=True, text=True
).stdout
The script writes a voice profile derived from a target account to a predictable file in /tmp without warning the user. On multi-user systems this can expose sensitive profiling data, enable overwrites/races, or leave artifacts behind that other local users or processes can access.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
analyze_script = Path(__file__).parent / "analyze_voice.py"
temp_profile = "/tmp/voice-profile-temp.json"
result = subprocess.run(
["python3", str(analyze_script), username, "--tweets", "30", "--output", temp_profile],
capture_output=True,
text=True
No suspicious patterns detected.