Back to skill

Security audit

GOG Stale Games Cleanup

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims by finding stale GOG games, emailing a report, and creating reminders, but users should review the email and reminder side effects before running it.

Use --dry-run first, confirm the selected Himalaya account and recipient, and be comfortable with game names, last-played dates, and install paths being sent by email. Only run the normal mode when you want it to create or modify Apple Reminders, and avoid enabling the cron example unless you want recurring side effects.

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

Warning
Location
scripts/sweep.sh:62
Finding

Unescaped Library Data Allows HTML Injection in Generated Email

Content
View full analysis

Vulnerability Details

File Location: scripts/sweep.sh, lines 62-76 and 104-111
Vulnerability Type: HTML injection caused by missing output encoding
Risk Level: Medium

Vulnerable Code

bash
ROW_IDX=0
while IFS= read -r line; do
  NAME=$(echo "$line" | jq -r '.name')
  LAST=$(echo "$line" | jq -r '.last_played // "Never"')
  PATH_=$(echo "$line" | jq -r '.install_path // "N/A"')
  BG=$([[ $((ROW_IDX % 2)) -eq 0 ]] && echo "" || echo "background:#fafafa")
  EMAIL_BODY+="<tr style='$BG'><td style='padding:6px'>$NAME</td><td style='padding:6px'>$LAST</td><td style='padding:6px'>$PATH_</td></tr>"
  echo "  • $NAME — last played ${LAST}"
  ROW_IDX=$((ROW_IDX + 1))
done < <(echo "$STALE" | jq -c '.[]')

EMAIL_BODY+="</table>"
EMAIL_BODY+="<p style='color:#888;margin-top:16px'>Generated by gog-stale-games-cleanup on $TODAY</p>"

The resulting value is sent explicitly as HTML:

bash
cat <<HEREDOC | himalaya --account "$EMAIL_ACCOUNT" template send
From: $(jq -r ".accounts.${EMAIL_ACCOUNT}.email" /root/.openclaw/workspace/config/himalaya.toml 2>/dev/null || echo "$RECIPIENT")
To: $RECIPIENT
Subject: $SUBJECT
Content-Type: text/html

$EMAIL_BODY
HEREDOC

Technical Analysis

The script reads name, last_played, and install_path from the supplied GOG library JSON and concatenates them directly into an HTML document. It does not encode HTML-sensitive characters such as &, <, >, ", or '.

Although the repository includes a JSON Schema, the script does not validate its input against that schema. Type validation alone would not address this issue because malicious HTML is still a valid JSON string. A crafted game name or installation path can therefore introduce arbitrary markup into the outgoing email.

For example, an attacker-controlled install_path could contain an external image element. When a mail client renders the message and permits remote images, it could contact an attacker-controlled server. Injected markup co ...[truncated 1540 chars]

Remediation
View remediation

Remediation Suggestions

  1. HTML-encode every value originating from the library JSON before adding it to EMAIL_BODY. At minimum, encode &, <, >, ", and '.
  2. Prefer a maintained template or serialization mechanism that applies contextual HTML escaping automatically rather than assembling markup through string concatenation.
  3. Validate the input JSON against references/gog_library_schema.json before processing it. Treat validation as defense in depth rather than a replacement for output encoding.
  4. Consider sending a plain-text report if HTML formatting is not essential.
  5. Add regression tests containing values such as:
    • <img src="https://attacker.invalid/track">
    • <a href="https://attacker.invalid">Review game</a>
    • Game & Expansion <Edition>
  6. Verify that test output contains encoded text, such as &lt;img, rather than executable markup.

A shell-compatible escaping helper could process each dynamic field before interpolation, but a structured HTML template library with automatic escaping is preferable.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The core functional behavior matches the declared purpose closely: it scans a GOG library, finds stale installed games, emails the list, and adds reminders. However, the declaration says there are no permissions, while the code clearly depends on and accesses external resources and tools: local library file input, email account/config resolution, sending email through Himalaya, and writing reminders through remindctl. This is a capabilities/permissions mismatch rather than a primary-purpose mismatch.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrases are broad enough that an agent could invoke this skill during ordinary conversation about game habits or cleanup, causing unintended side effects like sending email and creating reminders. Because the skill performs external actions, accidental invocation increases the risk of privacy leakage and unwanted modification of user data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script reads email account details from broader local configuration locations, including a workspace path under /root, even though its advertised function is game cleanup. This expands data access beyond the minimum necessary scope and can expose unrelated account information or cause the script to act on sensitive configuration the user did not intend to share with this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script silently inspects user and workspace email configuration to resolve an address without clearly disclosing that behavior in the file's user-facing flow. Hidden access to personal configuration is dangerous because users may believe the script only processes game metadata, while it actually reads unrelated local account settings.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script transmits local game metadata, including game names and install paths, via email without an explicit warning that this data will leave the local system. Install paths can reveal usernames, directory layouts, external volumes, or other environment details, making the disclosure more sensitive than a simple notification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script creates reminder lists and adds reminder items without prominent disclosure that it will modify the user's Apple Reminders data. Although this is consistent with the skill's stated purpose, silent modification of personal productivity data can still surprise users and cause unwanted state changes or clutter.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.