#9237: Fix: WhatsApp QR code not rendering in chat
app: web-ui
stale
Cluster:
WhatsApp Enhancements and Fixes
Fixes #9231
## Problem
When running the WhatsApp login tool via `/pair whatsapp` command or the `whatsapp_login` agent tool, the QR code was not displaying in the chat interface. Users saw a blank gray box instead of the QR code image.
## Root Cause
The markdown sanitizer in `ui/src/ui/markdown.ts` was configured to strip out `<img>` tags during HTML sanitization. The `allowedTags` array didn't include `"img"`, causing DOMPurify to remove all image tags from the rendered markdown.
When the WhatsApp login tool returns the QR code as markdown:
```markdown

```
The markdown renderer converted it to an `<img>` tag, but then DOMPurify stripped it out during sanitization, leaving no visible content.
## Solution
Added `"img"` to the `allowedTags` array and `"src"` + `"alt"` to the `allowedAttrs` array in the markdown sanitizer configuration. This allows:
- Images rendered from markdown to display properly
- Both `src` and `alt` attributes to be preserved for accessibility
- Data URLs (base64 encoded images) to work correctly
## Changes
- `ui/src/ui/markdown.ts`:
- Added `"img"` to `allowedTags` (line 23)
- Added `"alt"` and `"src"` to `allowedAttrs` (line 38, alphabetically sorted)
## Impact
✅ WhatsApp QR codes now render correctly in chat
✅ Other markdown images (if used elsewhere) will now work
✅ No breaking changes - only enables previously blocked feature
✅ Minimal security impact - DOMPurify still sanitizes other dangerous content
## Testing
- ✅ TypeScript compilation passes
- ✅ Code formatted with oxfmt
- ✅ Only 2 lines changed in 1 file
Manual testing needed: Run WhatsApp login tool and verify QR code displays in chat.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the UI markdown sanitizer (`ui/src/ui/markdown.ts`) to allow `<img>` tags and the `src`/`alt` attributes so markdown-rendered images (including the WhatsApp pairing QR code emitted as ``) are no longer stripped by DOMPurify and can display in chat/tool output renders.
The main behavioral change is that any sanitized markdown rendered via `toSanitizedMarkdownHtml()` can now include images.
<h3>Confidence Score: 3/5</h3>
- This PR is likely safe but expands markdown rendering surface area in a way that needs tighter constraints.
- Change is small and targeted, but allowing `<img src>` in sanitized user/assistant markdown can introduce a concrete privacy leak via remote image loads unless `src` is constrained (e.g., to `data:image/*`).
- ui/src/ui/markdown.ts
<!-- greptile_other_comments_section -->
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#7395: fix(whatsapp): strip markdown bold/italic from URLs before sending
by lailoo · 2026-02-02
81.1%
#10196: fix(whatsapp): sanitize raw mention IDs in outbound messages
by koala73 · 2026-02-06
78.6%
#2716: Fix #2678: markdown horizontal rules not rendering in web chat
by Ambar-13 · 2026-01-27
78.5%
#15204: fix(ui): preserve angle-bracketed text in chat
by bufordtjustice2918 · 2026-02-13
78.3%
#13764: feat(whatsapp): add --qr-png option to save QR code as PNG file
by aorfevre · 2026-02-11
77.0%
#9606: fix: pass fileName to WhatsApp document messages
by AytuncYildizli · 2026-02-05
76.7%
#13431: feat(whatsapp): add built-in Markdown to WhatsApp format transform
by asklee-klawd · 2026-02-10
76.4%
#22333: Fix webchat inline image rendering and size handling
by AIflow-Labs · 2026-02-21
75.7%
#16147: fix: use a single asterisk to wrap the bold text in whatsapp
by albertominetti · 2026-02-14
75.5%
#19303: Fix WhatsApp internal error leakage + cron.run timeout defaults
by koala73 · 2026-02-17
74.5%