Skip to content

fix(view/ssr): guard bq-bind attribute values against XSS sinks - #184

Merged
JosunLP merged 3 commits into
devfrom
fix/164-bq-bind-attribute-guard
Jul 6, 2026
Merged

fix(view/ssr): guard bq-bind attribute values against XSS sinks#184
JosunLP merged 3 commits into
devfrom
fix/164-bq-bind-attribute-guard

Conversation

@JosunLP

@JosunLP JosunLP commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #164 (High).

bq-bind wrote runtime data to any attribute with no validation:

  • <a bq-bind:href="link"> with link = "javascript:alert(document.cookie)" → clickable script execution
  • <div bq-bind:onclick="h"> → registered a live inline handler
  • <iframe bq-bind:srcdoc="msg"> (client and both SSR backends) → attribute-encoding is decoded by the browser and parsed as a full HTML document → script execution

Fix

New shared guard src/security/bind-guard.ts (checkBoundAttribute), reused by all three sinks (client directive, pure SSR renderer, legacy DOM SSR renderer):

  • on* names: never written; client logs a warning
  • srcdoc: treated as an HTML sink — sanitized via sanitizeHtml (client) / sanitizeHtmlForSSR (SSR)
  • URL attributes (href", src, xlink:href, formaction, action, poster, background, cite, data) + srcset`: values with dangerous protocols (after control-char/zero-width normalization) are dropped

Boolean/null semantics of bq-bind are unchanged; safe values pass through as before.

Verification

  • New client tests (href-drop + re-set on safe value, onclick never written, srcdoc sanitized) and SSR tests across both backends (href, onclick, srcdoc, safe-URL passthrough).
  • Confirmed 5 of the new tests fail without the src changes.
  • Full suite: 2997 pass / 0 fail. tsc --noEmit + eslint clean.

🤖 Generated with Claude Code

handleBind wrote any runtime value straight to setAttribute with no
protocol or attribute-name validation, so tainted context data could
inject javascript: URLs (href/src), inline handlers (bq-bind:onclick),
or a full HTML document via iframe srcdoc. The SSR renderers blocked
on* and a fixed URL list but also let srcdoc through, where attribute
encoding is no defense because the browser entity-decodes and parses it.

A shared guard (src/security/bind-guard.ts) now decides per attribute:
- on* names are never written (client warns)
- srcdoc is sanitized as an HTML sink (sanitizeHtml / sanitizeHtmlForSSR)
- URL attributes (href, src, xlink:href, formaction, action, poster,
  background, cite, data) and srcset drop values with dangerous protocols

Used by the client directive, the pure SSR renderer and the legacy
DOM-backed SSR renderer.

Fixes #164

Co-Authored-By: Claude Fable 5 <[email protected]>
@github-actions github-actions Bot added security Changes to the security module view Changes to the view module tests Chenges to the tests ssr Changes to the ssr module labels Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 071e72d9-7f5a-4afa-81d8-1085712b6534

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/164-bq-bind-attribute-guard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

JosunLP and others added 2 commits July 6, 2026 22:59
- ssr-stable.test.ts: the dev merge concatenated the #164/#176 EOF test
  appends and dropped the #164 block's closing braces (type-check syntax
  error).
- render.ts: the merge with #167 (which routed evaluateSSR through
  evaluateExpression) left the isComputed/isSignal/Signal import unused.

Co-Authored-By: Claude Fable 5 <[email protected]>
@JosunLP
JosunLP merged commit 295efd8 into dev Jul 6, 2026
9 checks passed
@JosunLP
JosunLP deleted the fix/164-bq-bind-attribute-guard branch July 6, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Changes to the security module ssr Changes to the ssr module tests Chenges to the tests view Changes to the view module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant