T09 · Insecure Skill Coding Practices
- Location
invoice_template.py:99- Finding
Stored HTML and Script Injection in Generated Invoices
- Content
View full analysis
{desc} {qty} {fmt(rate)} {fmt(amount)} """ ``` The completed HTML document also directly interpolates other values without escaping: ```python{logo_html}{business['name']}
{business['address'].replace(chr(10), '
')}{business['email']}
{business['phone']}
{f"{business['website']}
" if business['website'] else ""}``` ```pythonINVOICE
Invoice #: {invoice_number}
Date: {invoice_date}
Due Date: {due_date}
{status_text}``` ```python {f'''Bill To
{client.get('name', '')}
{client.get('email', '')}
{f"{client.get('address', '').replace(chr(10), '
" if client.get('address') else ""} {f"
')}{client.get('phone', '')}
" if client.get('phone') else ""}''' if payment_details else ''} {f'Payment Details
text {payment_details}Notes: {notes}' if notes else ''} {f'Terms: {terms}' if terms else ''} ...[truncated 2711 chars]- Remediation
View remediation
str: return escape(str(value), quote=True) ``` Use this helper for invoice numbers, descriptions, client fields, business fields, notes, terms, payment details, tax labels, discount information, and statuses. 2. Preserve intended line breaks only after escaping: ```python safe_address = html_text(address).replace("\n", "
") ``` Do not replace newlines before escaping, because that would also escape the intentionally inserted `
` elements. 3. Validate website and link values separately. Permit only explicitly supported schemes, such as `https`, rather than treating arbitrary configuration values as safe markup. 4. Prefer a maintained template engine with automatic HTML escaping if adding a dependency is acceptable. Keep automatic escaping enabled and use explicit safe-markup annotations only for internally generated markup. 5. Consider adding a restrictive Content Security Policy to generated HTML, for example one that blocks scripts and limits external resources. This is defense in depth and does not replace proper output encoding. 6. Add regression tests using payloads containing: ```text"> & < > " ' ``` The tests should verify that these values appear as encoded text and do not create executable elements or attributes. ]]>
