T09 · Insecure Skill Coding Practices
- Location
assets/template.html:523- Finding
DOM-Based Script Injection Through the Image Error Handler
- Content
View full analysis
'; ``` The HTML escaping helper used elsewhere in the renderer is: ```javascript function esc(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } ``` ### Technical Analysis The renderer interpolates `spot.name` into the JavaScript source of an inline `onerror` event handler. Although `encodeURIComponent()` is applied, it is not a JavaScript-string escaping function and does not encode every character that can affect this context. In particular, an apostrophe remains unencoded and can terminate the single-quoted `this.src` value. The `esc()` helper cannot address this issue because it is designed for HTML text and double-quoted attribute contexts, not for untrusted data embedded inside a JavaScript string inside an HTML attribute. This nested parser context requires avoiding source-code interpolation entirely. For example, a crafted attraction name shaped like: ```text '-alert(document.domain)-' ``` can produce an event handler structurally equivalent to: ```javascript this.src='data:image/svg+xml,...'-alert(document.domain)-'%3C/text%3E...'; ``` This is syntactically executable JavaScript. The injected expression is evaluated when the original image fails to load. The current bundle ...[truncated 1783 chars]- Remediation
View remediation
' + '' + '' + escapeXmlText(String(spot.name)) + ''; img.src = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg); }); return img; } function escapeXmlText(value) { return value .replace(/&/g, '&') .replace(//g, '>'); } ``` 2. **Prefer DOM construction over `innerHTML`.** Build dynamic cards with `createElement()`, `textContent`, `setAttribute()`, and `appendChild()`. This prevents data from crossing HTML and JavaScript parser boundaries. 3. **Validate generated itinerary fields.** Treat attraction names, image paths, transport text, and other generated fields as untrusted. Apply field-length limits and reject control characters where they are unnecessary. 4. **Encode by destination context.** Use `textContent` for visible text and direct property assignment for URLs. Do not use URL encoding as a substitute for JavaScript or HTML escaping. 5. **Add a restrictive Content Security Policy after removing inline handlers.** For example: ```html
