El bloque HTML raw de Gutenberg permite insertar código HTML personalizado directamente en posts, pero sin validación adecuada expone tu sitio a vulnerabilidades XSS almacenadas. La vulnerabilidad más crítica se registró en el Avatar Block de Gutenberg en 2022 (CVSS 8.7), y el problema de fondo sigue vigente: la documentación de Gutenberg sobre escaping de HTML es confusa, y los desarrolladores usan funciones inseguras sin saberlo.
En 30 segundos
- Gutenberg tiene un bloque HTML que acepta código raw sin escape automático si no lo configurás bien
- Las vulnerabilidades XSS en Gutenberg son reales: Avatar Block (2022, CVSS 8.7), Template Part Block (2023), y más detectadas por Wordfence
- Diferencia crítica:
RawHTMLno escapa,escape-htmlescapa todo,decodeEntitiesdecod sin limpiar — cada uno tiene un caso de uso diferente - Tenés que validar entrada, escapar output, sanitizar atributos — todo en el mismo bloque, o se colapsa la seguridad
- Solución para admins: deshabilitar el bloque HTML para colaboradores/autores, usar Wordfence para monitoreo, auditar posts existentes
¿Qué es el bloque HTML raw en Gutenberg?
El bloque HTML raw en Gutenberg es un componente que permite a editores insertar código HTML personalizado directamente en un post. No se trata de una medida peligrosa por defecto — tiene casos de uso legítimos: migraciones desde shortcodes legacy, embeds personalizados que no cubre Gutenberg, estructuras HTML complejas que los bloques estándar no permiten.
Pero acá está el problema. Ponele que tenés un post que alguna vez usó un shortcode tipo [mi-personalizado] que hacía cosas raras. En vez de reescribir todo, metés un bloque HTML raw con esa estructura. Lo que no ves es que ese HTML puede contener scripts inline, atributos on* sin escapar, o referencias a elementos que no existen (spoiler: cuando alguien edita ese post después, le hace click sin pensar y de repente ejecuta código que no debería ejecutarse).
Gutenberg por diseño no escapa automáticamente el HTML en el bloque raw. Eso es intencional — si escapara todo, no servía para nada. Pero significa que el desarrollador (el que crea un bloque personalizado con HTML raw) tiene que hacer el escaping manualmente. Y ahí es donde empieza la cagada.
Riesgos de seguridad: vulnerabilidades XSS en Gutenberg
Las vulnerabilidades XSS en Gutenberg son documentadas y reales. Wordfence registró una vulnerabilidad crítica en el Avatar Block (Gutenberg 12.9.0 a 18.0.0, CVSS 8.7) donde editores podían inyectar JavaScript a través del atributo de imagen. El Template Part Block tuvo problemas similares. En ambos casos, el bloque asumía que el atributo HTML era «confiable» (que no lo era).
¿Qué pasó? Exactamente lo que no querés: un editor hace click en «Editar Avatar Block», pega un atributo `onerror=»alert(document.cookie)»`, guarda el post, y cada usuario que ve ese post ejecuta ese JavaScript. Si el atacante es más sofisticado, roba cookies de sesión, redirige a phishing, o inyecta malware.
Lo grave es que XSS almacenado en Gutenberg afecta a todos los visitantes del sitio, no solo a editores. Un atacante con permisos de Editor (o Colaborador, dependiendo de la configuración) puede comprometer la experiencia de todos tus usuarios.
La causa de fondo: Gutenberg no tiene una lista explícita de atributos HTML «permitidos» para cada bloque. Los desarrolladores de bloques personalizados cargan lo que el cliente les pide, sin sanitizar. Y si el bloque usa RawHTML sin validación previa, todo el HTML se ejecuta tal cual.
Diferencia entre RawHTML, escape-html y decodeEntities
Estas tres funciones hacen cosas completamente distintas, pero el nombre no lo deja claro. Por eso hay tanta confusión en la documentación de Gutenberg.
| Función | Qué hace | Cuándo usarla | Seguro? |
|---|---|---|---|
RawHTML | Renderiza HTML tal cual, sin escape. Las entidades HTML se decodifican automáticamente. | Cuando el HTML ya fue validado y sanitizado antes de llegar a RawHTML. Raramente. | No, salvo que hayas sanitizado a mano todo lo que entra. |
escape-html (o wp.htmlEntities) | Convierte caracteres especiales en entidades HTML: < en lugar de <, " en ", etc. Nada se ejecuta. | Cuando necesitás mostrar HTML como texto (no renderizarlo). Si querés que el usuario vea el código fuente literalmente. | Sí. El contenido no se interpreta, se muestra como string. |
decodeEntities | Lo opuesto a escape-html: convierte entidades de vuelta a caracteres. < vuelve a <. | Cuando necesitás decodificar entidades pero no renderizar HTML. Rara situación. | Depende. Si después pasás el resultado a RawHTML, no es seguro. Si lo usás solo para comparación de strings, sí. |

La fila que causa el 90% de los problemas: RawHTML. Los desarrolladores leen el nombre, piensan «ah, para HTML raw», meten ahí lo que sea, y boom — XSS. Pero RawHTML no valida el HTML. Solo lo renderiza. Si pasás un `