Severity: 🟠 High
Location
Description
handleBind writes any attribute directly from runtime data with no protocol or attribute-name validation:
el.setAttribute(attrName, String(value));
The attribute name is template-controlled (trusted), but the value is runtime data — exactly the class the framework tells authors is safe to bind. This is inconsistent with bq-html, where sanitizeHtml blocks javascript: in href/src/action. bq-bind — the most common way to bind data to an attribute — has none of that.
Concrete exploits, all with tainted data in the context signal:
<a bq-bind:href="link"> with link = "javascript:alert(document.cookie)" → clickable script execution.
<img bq-bind:src="u"> / <iframe bq-bind:src="u"> with a javascript:/data: URL.
<div bq-bind:onclick="h"> with h = "alert(1)" → setAttribute('onclick', …) registers an inline handler.
SSR variant (srcdoc): the SSR bq-bind implementation does block on* and validates a fixed URL-attribute list, but srcdoc on <iframe> is neither, and <iframe> is not stripped by the serializers. Attribute-encoding is insufficient because the browser decodes entities and parses srcdoc as a full HTML document:
Input: <iframe bq-bind:srcdoc="msg"></iframe> msg = '<script>alert(1)</script>'
Output: <iframe ... srcdoc="<script>alert(1)</script>"></iframe> → executes
Suggested fix
In handleBind (and the SSR equivalents), for URL-bearing attributes (href, src, action, formaction, xlink:href, poster, background, srcset) run the value through the security module's isSafeUrl/isSafeSrcset and drop it on failure; refuse (or warn on) on* attribute names; treat srcdoc as an HTML sink (drop, sanitize, or require explicit opt-in). Prefer an allowlist of bind-target attributes over a denylist, and reuse src/security rather than re-implementing.
Filed as part of a full-codebase security & correctness audit.
Severity: 🟠 High
Location
src/view/directives/bind.ts:9-23(sink at:18)src/ssr/renderer.ts:470-517/src/ssr/render.ts(srcdocvariant)Description
handleBindwrites any attribute directly from runtime data with no protocol or attribute-name validation:The attribute name is template-controlled (trusted), but the value is runtime data — exactly the class the framework tells authors is safe to bind. This is inconsistent with
bq-html, wheresanitizeHtmlblocksjavascript:inhref/src/action.bq-bind— the most common way to bind data to an attribute — has none of that.Concrete exploits, all with tainted data in the context signal:
<a bq-bind:href="link">withlink = "javascript:alert(document.cookie)"→ clickable script execution.<img bq-bind:src="u">/<iframe bq-bind:src="u">with ajavascript:/data:URL.<div bq-bind:onclick="h">withh = "alert(1)"→setAttribute('onclick', …)registers an inline handler.SSR variant (
srcdoc): the SSRbq-bindimplementation does blockon*and validates a fixed URL-attribute list, butsrcdocon<iframe>is neither, and<iframe>is not stripped by the serializers. Attribute-encoding is insufficient because the browser decodes entities and parsessrcdocas a full HTML document:Suggested fix
In
handleBind(and the SSR equivalents), for URL-bearing attributes (href,src,action,formaction,xlink:href,poster,background,srcset) run the value through the security module'sisSafeUrl/isSafeSrcsetand drop it on failure; refuse (or warn on)on*attribute names; treatsrcdocas an HTML sink (drop, sanitize, or require explicit opt-in). Prefer an allowlist of bind-target attributes over a denylist, and reusesrc/securityrather than re-implementing.Filed as part of a full-codebase security & correctness audit.