Security
Strict CSP, Trusted Types and what to do on the server.
On this page
The editor works under a strict Content Security Policy with Trusted Types. This site itself runs under that policy.
Layers of defence
| Layer | What it does |
|---|---|
| Input | Every input path (initial content, setContent, paste, drop, source view) passes through DOMPurify. Script-capable elements are removed before parsing. |
| Model | Only schema-known content survives, unless HtmlSupport is added, and even then its blocklist applies. |
| Output | getHTML() is produced by a serializer that does not use the DOM. It validates tag and attribute names, escapes every value and checks every URL again. |
| URLs | Allowed by default: http, https, mailto and tel, plus relative URLs. data: images are off unless urlPolicy.allowDataImages is set. |
| CSP | Works under script-src 'self'; style-src 'self'; require-trusted-types-for 'script'. The live view never writes inline style strings. |
| Trusted Types | Adds one policy named open-wysiwyg-editor to your trusted-types directive, or pass your own with setTrustedTypesPolicy(). |
A recommended policy
Add the editor's policy name to trusted-types. Paste handling also uses ProseMirror's ProseMirrorClipboard policy, so list that one too.
Trusted Types
With require-trusted-types-for 'script', every HTML sink needs a trusted value. The editor creates one policy and uses it everywhere.
The browser is not a security boundary
Never trust HTML that comes from the client. The editor cleans what it loads and produces, but anyone can post any string to your API. Sanitize again on the server, with a library you trust, before you store or render it for other users.
For initial content from users, use the value attribute or a <template> child on <owe-editor>, never raw children. Neither can run anything before the editor sanitizes it.
Found a vulnerability? Please report it privately, see the security policy.