Malla ejecuta contenido no confiable, fórmulas de usuarios y entradas de visitantes junto a los secretos de los clientes. Estos son los límites que los mantienen separados.
Dos poblaciones que nunca se mezclan
Los usuarios del editor y los visitantes del sitio tienen tablas separadas, cookies de sesión separadas y claves de firma separadas. Las sesiones del editor son cookies HTTP-only, Secure y SameSite=Lax con comprobaciones CSRF; las contraseñas se hashean con scrypt. Las sesiones de los visitantes están limitadas al dominio del cliente y viven en la base de datos propia del sitio.
Autorización
- Cada ruta de la api comprueba el rol de quien llama en el sitio; los sitios desconocidos y los prohibidos responden 404 por igual.
- Las publicaciones en producción, los cambios de slug, los dominios y la escritura de integraciones requieren un administrador.
- Las salas en tiempo real verifican un token de corta duración y el sitio de la página; los lectores tienen solo lectura y los editores de contenido solo pueden cambiar texto.
- Realtime valida cada actualización contra los esquemas antes de guardarla o retransmitirla.
Expresiones
Ni eval ni new Function. El intérprete rechaza window, document, globalThis, constructor, __proto__ y prototype, no tiene asignaciones ni bucles, y limita la longitud del código, la profundidad, los nodos evaluados y el tamaño de textos y arrays. El mismo intérprete evalúa en el servidor las reglas de fila y las reglas de acceso a páginas.
El navegador no es de confianza
Los visitantes pueden leer y cambiar los flujos de trabajo de cliente y los enlaces de datos, así que estos nunca tienen autoridad. El acceso a las páginas se aplica en el servidor, las consultas de cliente de las páginas protegidas pasan por la misma barrera y las escrituras pasan por flujos de trabajo de servidor y reglas de fila. En las reglas, un user anónimo tiene id: NaN, así que las comprobaciones de propiedad nunca coinciden con filas sin propietario.
Solicitudes salientes
Las integraciones solo llegan a los hosts que declaran. Los fetch del servidor exigen HTTPS, resuelven los nombres de host con DNS-over-HTTPS y bloquean las respuestas privadas, de loopback y link-local (las redirecciones se vuelven a comprobar), y limitan el tiempo y el tamaño de la respuesta. runJs corre en un isolate de Worker Loader sin bindings y sin secretos.
Estilos y HTML
Los valores de estilo que podrían escaparse de una regla se rechazan; los nombres de propiedad se validan. El renderizador escapa el texto y sanea las URL. El texto enriquecido se guarda como JSON estructurado, nunca como HTML crudo. El código personalizado del sitio solo corre en los sitios publicados, nunca en el editor.
Protección contra abusos
Los formularios usan Turnstile, un honeypot y límites por IP y por formulario, y guardan las IP hasheadas. Los endpoints públicos, las consultas de cliente, el inicio de sesión y el registro usan el rate limiting de Cloudflare.