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.

Back to public demo