T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/gog-cleanup.sh:65
- Finding
- Unescaped GOG Metadata Allows HTML Injection into Email Digests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gog-cleanup.sh`, lines 65-79 **Vulnerability Type**: HTML injection caused by missing output encoding **Risk Level**: Medium ### Vulnerable Code ```bash email_subject="🧹 GOG Cleanup: ${game_count} game(s) to consider uninstalling" email_body="<html><body style='font-family:system-ui,sans-serif;color:#333;max-width:600px;margin:0 auto;padding:20px;'>" email_body+="<h2 style='color:#8b5cf6;'>🧹 GOG Game Cleanup Report</h2>" email_body+="<p>You have <strong>${game_count} installed game(s)</strong> that haven't been played in ${STALE_DAYS}+ days:</p>" email_body+="<table style='width:100%;border-collapse:collapse;margin:16px 0;'>" email_body+="<tr style='background:#f3f4f6;text-align:left;'><th style='padding:8px;border:1px solid #e5e7eb;'>Game</th><th style='padding:8px;border:1px solid #e5e7eb;'>Last Played</th><th style='padding:8px;border:1px solid #e5e7eb;'>Install Path</th></tr>" for line in "${lines[@]}"; do IFS=$'\t' read -r id name last_played install_path <<< "$line" email_body+="<tr><td style='padding:8px;border:1px solid #e5e7eb;'>${name}</td><td style='padding:8px;border:1px solid #e5e7eb;'>${last_played}</td><td style='padding:8px;border:1px solid #e5e7eb;font-size:0.85em;'>${install_path}</td></tr>" done ``` ### Technical Analysis The values `name`, `last_played`, and `install_path` originate from `config/gog_library.json`. They are interpolated directly into an HTML document without context-appropriate HTML encoding. Consequently, a metadata value containing HTML markup is interpreted as part of the message rather than displayed as text. For example, a crafted game name could introduce an external image, deceptive link, or modified table content. Whether scripts or other active elements execute depends on the recipient's email client, and most modern clients restrict JavaScript. However, remote resources, misleading links, and HTML-based content spoofing may remain effective ...[truncated 2296 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Apply HTML output encoding to every dynamic value before inserting it into the message body. At minimum, encode `&`, `<`, `>`, `"`, and `'`. A shell helper can perform the required escaping: ```bash html_escape() { local value=$1 value=${value//&/&} value=${value//</<} value=${value//>/>} value=${value//\"/"} value=${value//\'/'} printf '%s' "$value" } ``` Escape each field immediately before constructing the table row: ```bash safe_name=$(html_escape "$name") safe_last_played=$(html_escape "$last_played") safe_install_path=$(html_escape "$install_path") email_body+="<tr><td style='padding:8px;border:1px solid #e5e7eb;'>${safe_name}</td><td style='padding:8px;border:1px solid #e5e7eb;'>${safe_last_played}</td><td style='padding:8px;border:1px solid #e5e7eb;font-size:0.85em;'>${safe_install_path}</td></tr>" ``` Additional hardening measures: 1. Prefer a structured HTML-generation library or template engine that escapes interpolated values by default. 2. Consider sending a plain-text digest if rich HTML formatting is not essential. 3. Validate the expected types and formats of all fields in `gog_library.json` before processing them. 4. Restrict write access to the library file and secure any process that generates or imports it. 5. Add tests containing characters such as `<`, `>`, `&`, quotes, and sample HTML elements to verify that metadata is rendered strictly as text. 6. Ensure temporary email files retain restrictive permissions and are removed reliably with an `EXIT` trap, including when Himalaya or the script terminates unexpectedly. ]]>
