Back to skill

Security audit

Journalism Agent

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent journalism/newsletter helper, but its newsletter assembly script uses unsafe shared temporary paths and unescaped HTML rendering that users should review before installing.

Review this skill before installing, especially if you handle embargoed topics, private editorial plans, or newsletters sent to real recipients. Use it only in a trusted workspace, avoid running the assembler with elevated privileges, and inspect generated HTML and image URLs before distribution.

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/newsletter_assemble.py:64
Finding

Unescaped Newsletter Content Permits HTML and Attribute Injection

Content
View full analysis
' f'

{block.get("image_credit","")}

' ) paras = "".join(f"

{p}

" for p in block.get("paras", [])) return f""" {img_html}

{block.get('title','Untitled')}

{block.get('byline','')}  ·  {block.get('date','')}

{paras} """ def render_listing(block): """Render a single listing block to HTML.""" img_html = "" if block.get("image_url"): img_html = ( f'' ) venue = block.get("venue", "") dt = block.get("datetime", "") why = block.get("why", "") meta_parts = [] if venue: meta_parts.append(venue) if dt: meta_parts.append(dt) meta = "  ·  ".join(meta_parts) return f"""
{img_html}

{block.get("name","")}

{f'

{meta}

' if meta else ''}

{why}

{f'

More info →

' if block.get("url") else ""}
""" ``` Additional unsafe interpolation occurs in source and template rendering: ```python srcs = ", ".join(f'{u[:60]}' for u in parts.get("sources", [])) or "None" replacements = { "{{PUBLICATION_NAME}}": ctx.get("publication_name", "Newsletter"), "{{TAGLINE}}": ctx.get("tagline", ""), "{{DATE} ...[truncated 2869 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/newsletter_assemble.py:20
Finding

Predictable Shared Temporary Directory Allows Symlink Following and Input Tampering

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/newsletter_assemble.py:190
Finding

Fixed Output Path Enables Symlink-Based File Overwrite

Content
View full analysis
/path/to/target ``` 3. A user or service with greater write privileges runs the newsletter assembler. 4. The statement `open(OUTPUT_FILE, "w")` follows the symbolic link. 5. The target file is truncated and replaced with newsletter HTML. 6. Depending on the target selected and the assembler account's permissions, this may corrupt application data or configuration and cause service failure. ### Impact Assessment The attacker does not gain write access beyond that already possessed by the assembler process. The vulnerability instead acts as a confused-deputy primitive, allowing the attacker to select the destination of a write performed with ...[truncated 535 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (6)

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · assets/newsletter-template.html (reported line 7)May include surrounding context.

html
<meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{TITLE}}</title>
  <!-- Design tokens applied by design-agent. Do not use ad-hoc CSS values. -->
  <style>
    /* Base tokens — override with project DESIGN.md values */
    :root {

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill defines a workflow that references local files and an assembly script, but it does not declare an explicit tool scope or allowed-tools boundary. In an agent system, missing scope restrictions can let the runtime grant broader file read/write capabilities than users expect, increasing the chance of unintended file access or modification during newsletter/article assembly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description is broad enough to trigger on common writing, research, and newsletter requests, which can cause the skill to be invoked in situations where users did not intend its full workflow or third-party integrations. Over-broad matching is risky here because this skill performs web research, image sourcing, and document assembly, so accidental invocation may expand data handling and network activity beyond user expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to send search queries and image-generation prompts to a third-party service without any explicit notice or consent step. Those prompts may contain sensitive user topics, unpublished story ideas, names, event details, or proprietary editorial plans, causing unannounced external data disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This line explicitly directs the agent to transmit a user-derived query to an external domain. In the context of a journalism skill, search terms can encode confidential editorial subjects, embargoed investigations, or personally identifying event information, so the outbound request creates a real privacy and confidentiality risk.

Content

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

md
- Alt text: descriptive, specific, no "image of" or "photo of"
   - **NK Images Search** — primary image pipeline for articles and listings:
     ```bash
     curl "https://nkimages.com/api/public/images?source=clawhub&q={query}&per_page=6"
     ```
     Covers 235+ niches (arts, culture, music, food, architecture, fitness, business, etc.).
     No API key required. Free commercial use. Use `viewUrl` and `downloadUrl` exactly as returned by the API.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML root sets lang="en", which is a natural-language locale choice embedded in the file. Under the policy, forcing a specific language/locale without user opt-in can be a violation when no alternative or justification is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.