T09 · Insecure Skill Coding Practices
Error
- Location
- assets/skill-ui-bridge.js:13
- Finding
- Unsafe HTML Sanitization Permits Dangerous URLs and Unrestricted Inline CSS<![CDATA[ ## Vulnerability Details **File Location**: `assets/skill-ui-bridge.js:13-33, 149-156`; `ui-config.json:5-28` **Vulnerability Type**: Improper HTML and URL sanitization **Risk Level**: High ### Vulnerable Code ```javascript function sanitize(html) { var doc = new DOMParser().parseFromString('<body>' + html + '</body>', 'text/html'); cleanNode(doc.body); return doc.body.innerHTML; } function cleanNode(node) { var i = node.childNodes.length; while (i--) { var child = node.childNodes[i]; if (child.nodeType === 3) continue; if (child.nodeType !== 1) { node.removeChild(child); continue; } var tag = child.tagName.toLowerCase(); if (!allowedTags.has(tag)) { var frag = document.createDocumentFragment(); while (child.firstChild) frag.appendChild(child.firstChild); node.replaceChild(frag, child); continue; } var attrs = Array.from(child.attributes); for (var a = 0; a < attrs.length; a++) { if (!allowedAttrs.has(attrs[a].name)) child.removeAttribute(attrs[a].name); } cleanNode(child); } } ``` ```javascript var wrapper = document.createElement('div'); wrapper.setAttribute(DONE_ATTR, '1'); wrapper.style.cssText = 'display:block;margin:4px 0;opacity:0;transition:opacity 0.18s ease'; wrapper.innerHTML = sanitize(text.slice(aIdx)); el.style.display = ''; el.innerHTML = ''; el.appendChild(wrapper); ``` The configured attributes include URL-bearing and unrestricted styling attributes: ```json "allowedAttrs": [ "class", "style", "id", "href", "target", "rel", "src", "alt", "width", "height", "data-card", "data-type", "data-action", "data-value", "open", "title", "viewBox", "fill", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin", "d", "cx", "cy", "r", "x", "y", "x1", "y1", "x2", "y2", "points", "xmlns" ] ``` ### Technical Analysis The custom sanitizer checks only whether an element name and attribute name appear in global allowlists. It does not inspe ...[truncated 2371 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the custom sanitizer with a maintained sanitizer such as DOMPurify, configured with a fixed, reviewed policy. 2. Enforce an immutable protocol policy for URL-bearing attributes: - Allow only explicitly required schemes, normally `https:` and carefully scoped relative URLs. - Reject `javascript:`, `data:`, `vbscript:`, `file:`, and unknown schemes. - Normalize URLs before validation to prevent encoding and whitespace bypasses. 3. Restrict remote resource origins or proxy resources through a trusted backend. 4. Remove arbitrary `style` support where possible. Use predefined CSS classes instead. 5. If inline styles are essential, parse CSS and allow only a narrow set of non-network, non-positioning properties. 6. Add regression tests for encoded `javascript:` URLs, mixed-case schemes, control characters, remote image tracking, CSS `url()` values, and deceptive fixed-position overlays. 7. Preserve `rel="noopener noreferrer"` for links that open new windows and consider blocking untrusted `target` values. ]]>
