Security
Last updated: May 25, 2026. This page describes upload sanitization for the cloud workspace and public demo import. It is not a penetration-test report or a certification.
We remove active content from uploaded HTML before storing or previewing it. That reduces script-based attacks between collaborators but does not make shared documents risk-free.
When sanitization runs
The same rules run on the client before send (early feedback) and again in Convex mutations on upload and HTML replace (authoritative). Stored HTML is also re-sanitized on read in Convex getDocument (defense in depth for legacy rows). Applies to: Cloud upload; Cloud HTML replace; Public demo import.
What we remove
Stripped tags (representative):
- script
- iframe
- object
- embed
- form
- input
- button
- textarea
- select
- video
- audio
- base
- template
- noscript
- frame
- frameset
- applet
- layer
- marquee
Stripped attributes and handlers:
- onclick
- ondblclick
- onmousedown
- onmouseup
- onmouseover
- onmousemove
- onmouseout
- onkeydown
- onkeyup
- onkeypress
- onfocus
- onblur
- onchange
- onsubmit
- onreset
- onload
- onunload
- onerror
- onabort
- onresize
- onscroll
- oninput
- oninvalid
- onsearch
- onselect
- onwheel
- oncopy
- oncut
- onpaste
- onbeforeunload
- onhashchange
- onpopstate
- onmessage
- onstorage
- srcdoc
Other behaviors:
- javascript: and vbscript: URLs in links and media
- data: URLs on links (images may use https only)
- meta http-equiv refresh and similar redirect metas
- Forged comment highlights (.doc-comment-mark / data-thread-id) on upload and replace
- Active embeds (iframes, plugins, forms)
What we still allow
- Static HTML document structure (head, body, sections, prose)
- Tables, lists, figures, and inline code
- Embedded SVG diagrams (paths, text, markers, foreignObject)
- Document CSS in style blocks and style attributes (filtered)
- https/http/mailto links and https images
- Server-written comment marks after comments exist (not on fresh upload/replace)
Interactive JavaScript in uploaded documents is not supported.
Known gaps
Not a guarantee
Allowlist sanitization reduces common script-based attacks but cannot cover every browser or parser edge case. The library and rules need ongoing maintenance as HTML features evolve.
Same-origin preview
Previews still render in same-origin srcDoc iframes without a sandbox. Defense is stripped markup, not iframe isolation. Residual CSS or markup tricks may still affect viewers.
CSS and external resources
Styles may reference external fonts or images. That is mainly a privacy/tracking concern, not full script execution, but uploaded HTML can still load third-party assets.
No interactive JavaScript
Documents that require client-side scripts will not work after sanitization. The product treats shared HTML as static content.
Legacy documents
Rows uploaded before sanitization shipped are re-sanitized on read in Convex getDocument; forged marks outside active comment threads are stripped.
Sharing model unchanged
Public documents remain visible to any signed-in user with the link. Sanitization does not replace access control or fix invite enumeration or postMessage hardening tracked separately.
HTTP security headers
The Next.js app shell sends Content-Security-Policy, X-Frame-Options, Referrer-Policy, and related headers via next.config.ts. CSP covers Clerk, Convex, and PostHog on /app. It does not sandbox user HTML inside preview iframes (same-origin srcDoc); upload sanitization and access control remain the primary defenses there.
Related
Data handling and subprocessors: Privacy. Upload size limits and replace behavior: Terms of use.