Seguridad y sanitización
Capas de defensa
Sección titulada «Capas de defensa»| Capa | Qué hace | Dónde |
|---|---|---|
| 1. Schema Tiptap | Solo permite nodos/marks del preset activo | Editor (cliente) |
| 2. Output sanitizado | buildOutput() sanitiza el HTML emitido | Editor (cliente) |
| 3. Viewer | DOMPurify antes de innerHTML | Viewer (cliente) |
| 4. Backend | Debe validar/sanitizar antes de persistir | Servidor (responsabilidad de Prolibu) |
Siempre bloqueado (todos los presets)
Sección titulada «Siempre bloqueado (todos los presets)»- Tags:
<script>,<object>,<embed>,<form>,<textarea>,<style> - URLs:
javascript:enhref(DOMPurify default) - Atributos: todos los
on*event handlers (onerror,onload,onclick, etc.) - Iframes: solo se permiten en el preset
document, y solo consrchttps:(regexSAFE_IFRAME_SRC_RE; bloqueahttp:,data:yjavascript:). No hay whitelist de dominios — cualquier URLhttps:la satisface (YouTube, Vimeo, Loom, Google Slides…). style: solo en email/document, y capado acolor,background-colorytext-align; se descartan declaraciones conurl()/expression()y el atributo entero si queda vacío.
Whitelist por preset
Sección titulada «Whitelist por preset»| Preset | Tags permitidos | Atributos extras |
|---|---|---|
| comment | p, br, strong, em, a, span | href, target, rel, data-mention-* |
| task | + u, s, code, ul, ol, li, blockquote, input, label | + type, checked, disabled, data-type, data-checked, data-variant |
| + h2, h3, div, img | + style, data-variable, src, alt, width, height, data-file-id, data-image-layout | |
| document | + h1–h4, hr, div, mark, img, table, thead, tbody, tr, th, td, input, label, iframe | + style, data-variable, colspan, rowspan, src, alt, width, height, type, checked, disabled, allowfullscreen, frameborder, allow, loading |
Checkboxes en task lists
Sección titulada «Checkboxes en task lists»Los <input type="checkbox"> de las task lists se permiten mediante un hook de DOMPurify que filtra por tipo. Cualquier otro <input> se elimina.
Imágenes y base64
Sección titulada «Imágenes y base64»- Actualmente:
allowBase64: true— pegar una imagen produce<img src="data:image/...">. - Para producción: se recomienda usar
imageUploadpara subir a CDN y reemplazar el base64 por una URLhttps:.
<co-rich-text-editor preset="document" .imageUpload=${async (file) => { const url = await uploadToCDN(file); return url; // reemplaza el base64 placeholder }}></co-rich-text-editor>Sanitizador standalone
Sección titulada «Sanitizador standalone»El sanitizador se puede importar sin cargar Tiptap:
import { sanitize } from '@prolibu-suite/cobalt-rich-text';
const clean = sanitize(dirtyHtml, 'task');Agregar un tag/atributo nuevo
Sección titulada «Agregar un tag/atributo nuevo»Debe hacerse en dos lugares simultáneamente:
sanitizer.ts→SANITIZE_CONFIGS[preset].ALLOWED_TAGS/ALLOWED_ATTRco-rich-text-viewer.tsx→ su copia local deALLOWED_TAGS/ALLOWED_ATTR
Además, el nodo debe estar registrado en el schema (preset o customExtensions) o el output lo eliminará.