Pulsa ESC para cerrar

Curso WordpressCurso Wordpress

unfiltered_html: el permiso que deja a tus editores insertar cualquier código

WordPress tiene un permiso con nombre técnico, unfiltered_html, que decide algo importante: si un usuario puede publicar cualquier código HTML y JavaScript, o si WordPress lo limpia antes de guardarlo.

En un sitio normal (no multisitio), lo tienen los administradores y los editores. Los autores y colaboradores no: si pegan un <script>, WordPress lo quita al guardar.

Por qué existe

Para que puedas pegar el código de un video, un mapa, un formulario externo o un píxel de seguimiento dentro de una entrada. Sin ese permiso, WordPress eliminaría las etiquetas <script> y <iframe>, y esos insertados no funcionarían.

El riesgo que pocos ven

Imagina que la contraseña de un editor se filtra. El atacante no puede instalar plugins ni crear usuarios, porque un editor no tiene esos permisos. Pero sí puede publicar un JavaScript en una entrada o página.

Cuando tú, la administradora o el administrador, abras esa entrada (en el sitio o en la vista previa), el script se ejecuta con tu sesión. Y desde ahí puede hacer lo que tú puedes: crear un administrador nuevo, instalar un plugin o cambiar tu correo.

Es una de las formas más comunes de escalar desde una cuenta menor a tomar el control del sitio.

Lo mismo aplica a plugins que permiten a roles bajos insertar código (constructores visuales, campos personalizados, widgets de HTML). Revisa qué roles pueden usarlos.

Opción 1: quitárselo a todos

Si nadie en tu sitio necesita pegar scripts en el contenido (lo normal en muchos blogs), agrega esta línea a wp-config.php:

define( 'DISALLOW_UNFILTERED_HTML', true );

Desde ese momento, ni los administradores pueden guardar <script> en el contenido. Los insertados de YouTube, Vimeo y otros servicios conocidos siguen funcionando, porque WordPress los maneja con el bloque Insertar, no con HTML pegado.

Opción 2: quitárselo solo a los editores

Si el administrador sí necesita pegar códigos, pero los editores no, usa un mu-plugin. Guárdalo como wp-content/mu-plugins/cwp-sin-unfiltered.php:

<?php
/**
 * Plugin Name: Editores sin unfiltered_html (Curso WordPress)
 */

add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id ) {
	if ( 'unfiltered_html' !== $cap ) {
		return $caps;
	}
	$usuario = get_userdata( $user_id );
	if ( $usuario && ! in_array( 'administrator', (array) $usuario->roles, true ) ) {
		$caps[] = 'do_not_allow';
	}
	return $caps;
}, 10, 3 );

Este método es mejor que quitar el permiso del rol en la base de datos: si algún plugin vuelve a agregarlo, el filtro lo sigue bloqueando.

¿Y dónde pongo los scripts que sí necesito?

Los códigos de seguimiento (Analytics, píxeles, verificaciones) no deberían ir dentro de entradas, sino en el <head> o el pie del sitio, cargados desde un mu-plugin o desde el plugin que corresponda:

add_action( 'wp_head', function () {
	?>
	<!-- Aquí tu código de seguimiento -->
	<?php
} );

Así quedan en un solo lugar, solo los cambia quien tiene acceso a los archivos y no dependen de que un editor tenga permisos de más.

Comprueba quién lo tiene

wp cap list administrator | grep unfiltered
wp cap list editor | grep unfiltered

Después de aplicar la opción 1 o 2, el permiso puede seguir apareciendo en la lista del rol, pero WordPress lo negará al usarlo. Para probarlo de verdad, entra como editor, pega <script>alert(1)</script> en un bloque HTML personalizado, guarda y recarga: el script debe haber desaparecido.

¿Usas algún plugin que deja a otros roles insertar código? Cuéntanos cuál en el foro y revisamos cómo limitarlo.