T09 · Insecure Skill Coding Practices
Error
- Location
- templates/index.html:232
- Finding
- Stored DOM-Based Cross-Site Scripting Through Indexed Email Metadata<![CDATA[ ## Vulnerability Details **File Location**: `templates/index.html`, lines 232-241 **Vulnerability Type**: Stored DOM-based cross-site scripting **Risk Level**: High ### Vulnerable Code ```javascript data.results.forEach(email => { const row = document.createElement('tr'); row.className = 'email-row'; let html = ` <td class="text-muted small" onclick="window.open('/email/${email.id}', '_blank')">${email.sent_time}</td> <td class="text-truncate" style="max-width: 250px;" onclick="window.open('/email/${email.id}', '_blank')">${email.sender}</td> <td class="fw-medium" onclick="window.open('/email/${email.id}', '_blank')">${email.subject}</td> `; if (showAdmin) { html += `<td><span class="delete-btn" onclick="deleteEmail(event, ${email.id})">🗑️</span></td>`; } row.innerHTML = html; resultsBody.appendChild(row); }); ``` ### Technical Analysis The sender, subject, and date values originate in EML headers and are stored without content sanitization. The search API returns these fields as JSON, after which the browser interpolates them into an HTML string and assigns that string to `innerHTML`. JSON encoding does not make values safe for insertion into an HTML parsing context. A malicious EML header containing HTML event handlers or other executable markup will therefore be parsed and executed by the browser. The detail template uses Jinja autoescaping, but that protection does not apply to this client-side `innerHTML` operation. ### Attack Path 1. An attacker sends or supplies an EML file with a malicious `Subject`, `From`, or `Date` header. 2. `indexer.py` parses the header and stores the malicious value in SQLite. 3. A permitted user or administrator opens the search page. 4. The `/search` endpoint returns the malicious value in JSON. 5. The page inserts it into `row.innerHTML`. 6. The payload executes in the EML indexer's browser origin. 7. If the victim has entered administrator Basi ...[truncated 570 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not concatenate email fields into HTML strings. - Create each table cell with DOM APIs and assign untrusted values through `textContent`. - Register click handlers with `addEventListener` instead of inline `onclick` attributes. - Apply a restrictive Content Security Policy that disallows inline scripts and event handlers. - Treat all parsed EML fields as untrusted, regardless of who imported the source directory. Example: ```javascript const senderCell = document.createElement('td'); senderCell.textContent = email.sender; senderCell.addEventListener('click', () => { window.open(`/email/${encodeURIComponent(email.id)}`, '_blank'); }); row.appendChild(senderCell); ``` ]]>
