Back to skill

Security audit

X Voice Match

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (2)

T01 · Skill Instruction Hijacking

Warning
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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_post.py:20
Finding

Predictable Shared Temporary Profile Path Allows Symlink-Based File Overwrite

Content
View full analysis
Dict[str, Any]: """Quick analysis if no profile exists""" 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 ) if result.returncode != 0: raise RuntimeError(f"Analysis failed: {result.stderr}") return load_profile(temp_profile) ``` The analyzer subsequently opens that path for writing without preventing symbolic-link traversal: ```python # Save with open(args.output, 'w') as f: json.dump(profile, f, indent=2) ``` ### Technical Analysis `/tmp` is normally shared among local users and processes. The constant filename `/tmp/voice-profile-temp.json` is known in advance and is not created atomically. Before the Skill runs, another local process can create that path as a symbolic link to a file writable by the account executing the Skill. Python's ordinary `open(path, 'w')` follows symbolic links and truncates the resolved target before writing the JSON profile. The code also leaves the temporary profile in place after use. Concurrent or repeated executions can collide, overwrite one another's profiles, or read data generated by another invocation. Exploitation requires local access sufficient to create an entry in `/tmp`, but it does not require permission to write directly to the final target. The write occurs with the privileges of the user running the Skill. ### Attack Path 1. A local attacker identifies that the Skill ...[truncated 1506 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/generate_post.py (reported line 96)May include surrounding context.

python
Generate posts that would make someone think "{profile['account']} definitely wrote this."
"""
    
    return prompt

def generate_via_llm(prompt: str) -> List[Dict[str, Any]]:
    """

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
97% confidence
Finding

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.

Content

Scanner excerpt · scripts/generate_post.py (reported line 142)May include surrounding context.

python
# 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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/analyze_voice.py (reported line 22)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/analyze_voice.py (reported line 240)May include surrounding context.

python
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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/generate_post.py (reported line 24)May include surrounding context.

python
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

Static analysis

No suspicious patterns detected.