T09 · Insecure Skill Coding Practices
Error
- Location
- generate-invoice.sh:55
- Finding
- Stored HTML and Script Injection in Generated Invoices<![CDATA[ ## Vulnerability Details **File Location**: `generate-invoice.sh:55-56`, `generate-invoice.sh:70-82`; injection sinks in `template.html:6`, `template.html:40-42`, `template.html:49`, `template.html:54-55`, and `template.html:62-64` **Vulnerability Type**: Unescaped HTML injection **Risk Level**: High ### Vulnerable Code ```bash ITEM_ROWS_HTML+=" <tr><td>${desc}</td><td>${qty}</td><td>${rate_fmt}</td><td>${amt_fmt}</td></tr>\n" ITEM_ROWS_MD+="| ${desc} | ${qty} | ${rate_fmt} | ${amt_fmt} |\n" ``` ```bash TPL=$(cat "$SCRIPT_DIR/template.html") TPL="${TPL//\{\{INVOICE_NUMBER\}\}/$INVOICE_NUMBER}" TPL="${TPL//\{\{DATE\}\}/$DATE}" TPL="${TPL//\{\{DUE_DATE\}\}/$DUE}" TPL="${TPL//\{\{FROM\}\}/$FROM}" TPL="${TPL//\{\{CLIENT\}\}/$CLIENT}" TPL="${TPL//\{\{CLIENT_EMAIL\}\}/$CLIENT_EMAIL}" TPL="${TPL//\{\{CURRENCY\}\}/$CURRENCY}" TPL="${TPL//\{\{SUBTOTAL\}\}/$SUBTOTAL}" TPL="${TPL//\{\{TAX_RATE\}\}/$TAX}" TPL="${TPL//\{\{TAX_AMOUNT\}\}/$TAX_AMOUNT}" TPL="${TPL//\{\{TOTAL\}\}/$TOTAL}" ROWS=$(echo -e "$ITEM_ROWS_HTML") TPL="${TPL//\{\{ITEMS_ROWS\}\}/$ROWS}" ``` Representative template sinks include: ```html <title>Invoice {{INVOICE_NUMBER}}</title> ``` ```html <div><strong>{{INVOICE_NUMBER}}</strong></div> <div>Date: {{DATE}}</div> <div>Due: {{DUE_DATE}}</div> ``` ```html <div>{{FROM}}</div> <div>{{CLIENT}}</div> <div>{{CLIENT_EMAIL}}</div> ``` ```html <tbody> {{ITEMS_ROWS}} </tbody> ``` ### Technical Analysis The command-line fields are treated as trusted HTML and substituted directly into the template. No HTML encoding is performed for client names, email addresses, invoice identifiers, dates, sender names, currency values, or item descriptions. An attacker can therefore close the surrounding HTML element and insert arbitrary markup or active content. For example, a crafted client or item description could contain a `<script>` element, an element with an event handler, an external tracking resource, or deceptive invoice markup. Because this paylo ...[truncated 1595 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Add a dedicated HTML-encoding function that replaces at least: - `&` with `&` - `<` with `<` - `>` with `>` - `"` with `"` - `'` with `'` 2. Encode every user-controlled text field before inserting it into the template, including item descriptions and all invoice metadata. 3. Prefer a template engine that performs automatic context-aware escaping rather than Bash string substitution. 4. Do not attempt to secure the output through blacklist filtering; encode data according to its HTML context. 5. Consider applying a restrictive Content Security Policy to generated documents as defense in depth, while recognizing that CSP does not replace output encoding. 6. Replace `echo -e` with `printf '%s'` so backslash sequences in generated content are not interpreted unexpectedly. 7. Add security tests using script tags, event-handler attributes, malformed closing tags, quotes, ampersands, multiline input, and external resource elements. ]]>
