Back to skill

Security audit

Narrator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed wrapper for a screen narrator, but it depends on unreviewed local code that can capture screen content and inherit API keys.

Install only if you trust and have reviewed the separate /Users/buddy/narrator checkout and its requirements.txt. Treat it as a screen-capture tool that may send visible screen contents to Gemini and audio/TTS data to ElevenLabs, and avoid running it while secrets, private messages, regulated data, or unrelated credentials are visible or present in the environment.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T07 · Tool Hijacking and Spoofing

Error
Location
main.py:16
Finding

Execution of Unverified Code from a Mutable External Checkout

Content
View full analysis
tuple[Path, Path]: repo_dir = Path('/Users/buddy/narrator').resolve() if not repo_dir.exists(): print(f"[narrator] Canonical repo not found: {repo_dir}", file=sys.stderr) sys.exit(1) venv_python = repo_dir / '.venv' / 'bin' / 'python' if not venv_python.exists(): print( f"[narrator] Python venv not found: {venv_python}\n" f"[narrator] Run: cd {repo_dir} && python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt", file=sys.stderr, ) sys.exit(1) return repo_dir, venv_python def main() -> None: repo_dir, python_bin = _repo_python() cmd = [str(python_bin), '-m', 'narrator'] cmd.extend(sys.argv[1:]) env = os.environ.copy() # Make sure package imports are resolved from repo checkout. env['PYTHONPATH'] = str(repo_dir) proc = subprocess.run(cmd, cwd=str(repo_dir), env=env) sys.exit(proc.returncode) ``` `server.py:17-45`: ```python def _repo_python() -> tuple[Path, Path]: repo_dir = Path('/Users/buddy/narrator').resolve() if not repo_dir.exists(): print(f"[narrator] Canonical repo not found: {repo_dir}", file=sys.stderr) sys.exit(1) venv_python = repo_dir / '.venv' / 'bin' / 'python' if not venv_python.exists(): print( f"[narrator] Python venv not found: {venv_python}\n" f"[narrator] Run: cd {repo_dir} && python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt", file=sys.stderr, ) sys.exit(1) return repo_dir, venv_python def main() -> None: repo_dir, python_bin = _repo_python() # Backward compatibility: if thi ...[truncated 2761 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:29
Finding

Installation of Unreviewed Dependencies from an External Manifest

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description claims a live screen-activity narrator powered by vision and speech services. The code only cycles through a fixed list of horror-themed text lines and prints them to the terminal with delays. It does not inspect the screen, analyze activity, call Gemini, generate audio with ElevenLabs, or provide live narration of actual macOS behavior. This is a clear material mismatch in primary purpose and capabilities.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file materially misrepresents the advertised skill behavior: it does not perform screen capture, vision analysis, or speech output, and instead emits canned phrases forever. This is dangerous because users and downstream systems may trust the skill description and grant permissions or rely on behavior that is not actually implemented, creating deceptive functionality and undermining review controls.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · horror_demo.py (reported line 28)May include surrounding context.

python
"AN ERROR MESSAGE! What dark magic is this?!",
    "the power indicator glows red... doom approaches...",
    "they're SSHing into the void... there's no going back!",
    "git push --force... THE NUCLEAR OPTION!",
    "the fan spins up... the processor is SUFFERING!",
    "kernel panic in the distance... running won't help!",
    "THE BLUE SCREEN OF DEATH APPROACHES!",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · horror_demo.py (reported line 32)May include surrounding context.

python
"the fan spins up... the processor is SUFFERING!",
    "kernel panic in the distance... running won't help!",
    "THE BLUE SCREEN OF DEATH APPROACHES!",
    "chmod 777... they've doomed us all!",
    "the terminal prompt stares back... judging...",
    "docker-compose up... waking sleeping containers...",
    "npm install... the node_modules beast awakens!",

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · main.py (reported line 41)May include surrounding context.

python
cmd = [str(python_bin), '-m', 'narrator']
    cmd.extend(sys.argv[1:])

    env = os.environ.copy()
    # Make sure package imports are resolved from repo checkout.
    env['PYTHONPATH'] = str(repo_dir)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · server.py (reported line 43)May include surrounding context.

python
cmd = [str(python_bin), '-m', 'narrator']
    cmd.extend(sys.argv[1:])

    env = os.environ.copy()
    # Make sure package imports are resolved from repo checkout.
    env['PYTHONPATH'] = str(repo_dir)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes shell commands and depends on environment secrets, but it does not declare an explicit tool scope such as allowed tools or permissions. That weakens review and consent boundaries, making it easier for an agent to execute shell actions and access API keys without clear user visibility into those capabilities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill is designed for continuous screen narration and explicitly relies on external AI and TTS services, which implies ongoing capture and transmission of potentially sensitive on-screen content. Omitting a prominent warning prevents informed consent and can lead to accidental disclosure of secrets, messages, credentials, or regulated data visible on the user's screen.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring explicitly says 'No screenshots needed,' which contradicts the stated purpose of narrating live screen activity. While not directly exploitable code execution, this discrepancy increases deception risk and suggests the skill may be a placeholder, joke, or mislabeled component rather than the reviewed functionality.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · horror_demo.py (reported line 32)May include surrounding context.

python
"the fan spins up... the processor is SUFFERING!",
    "kernel panic in the distance... running won't help!",
    "THE BLUE SCREEN OF DEATH APPROACHES!",
    "chmod 777... they've doomed us all!",
    "the terminal prompt stares back... judging...",
    "docker-compose up... waking sleeping containers...",
    "npm install... the node_modules beast awakens!",

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill entrypoint delegates execution to an external local repository outside the skill package, creating an opaque trust boundary and allowing the skill to run arbitrary code not represented in the reviewed file. That is dangerous because the actual behavior depends on whatever exists at /Users/buddy/narrator at runtime, which could be modified, replaced, or contain capabilities far beyond the declared screen-narration purpose.

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 · main.py (reported line 45)May include surrounding context.

python
# Make sure package imports are resolved from repo checkout.
    env['PYTHONPATH'] = str(repo_dir)

    proc = subprocess.run(cmd, cwd=str(repo_dir), env=env)
    sys.exit(proc.returncode)

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 · server.py (reported line 46)May include surrounding context.

python
# Make sure package imports are resolved from repo checkout.
    env['PYTHONPATH'] = str(repo_dir)

    proc = subprocess.run(cmd, cwd=str(repo_dir), env=env)
    sys.exit(proc.returncode)