La falla en un párrafo, el resto es procedimiento
CVE-2026-85097 afecta a Bricksforge 3.1.8.9 y versiones anteriores; la corrección es la versión 3.1.8.10. El módulo Pro Forms comprueba el tipo MIME de un archivo en el primer envío, pero al enviar el formulario confía en el campo url aportado por el cliente dentro del parámetro temporaryFileUploads. Un archivo políglota GIF/PHP supera la comprobación y luego se referencia con una URL de destino PHP: el servidor lo escribe allí y lo ejecuta en la primera solicitud.
Sobre la gravedad, las fuentes difieren: crítica, con una puntuación CVSS de 9,8 según SecurityWeek y de 10,0 según el aviso de Patchstack. No tomamos partido, la conducta a seguir es la misma. Patchstack observó las primeras explotaciones el 7 de octubre de 2026, antes de la divulgación (aviso del 8 de octubre), y SecurityWeek, en su artículo del 12 de octubre, cita unos 6000 sitios con el plugin. Las listas de direcciones IP atacantes son efímeras: están en el aviso de Patchstack, no hace falta copiarlas.
Tabla de referencia: dónde mirar, qué buscar
Desplace la tabla
| Dónde mirar | Qué buscar | Qué indica |
|---|---|---|
| Versión del plugin | Bricksforge 3.1.8.9 o anterior | Vulnerable: pasar a 3.1.8.10 o posterior |
| Plugin ausente o desactivado | Ninguna línea en el inventario wp-cli | Sin exposición por este plugin, anótelo igualmente |
| `wp-content/uploads/bricksforge/tmp/` | Cualquier archivo PHP | Depósito probable: tratar el sitio como comprometido |
| `wp-content/uploads/AAAA/MM/` | Archivos `login_admin_*.php` | Objetivo citado por Patchstack: tratar el sitio como comprometido |
| Registros de acceso | POST a `/wp-json/bricksforge/v1/form_submit` | Intento: contrastar con el estado del disco |
| Registros de acceso | `admin-ajax.php` con `bricksforge_form_submit` o `bricksforge_regenerate_nonce` | Intento: el nonce se pide antes del envío |
| Registros de acceso | Solicitud a un archivo PHP bajo `uploads/` | Ejecución probable: rotación de secretos |
| Cuentas de WordPress | Administrador reciente y desconocido | Posible persistencia: valorar una restauración |
Por qué actualizar no basta
La explotación precedió a la corrección. Un sitio pasado a 3.1.8.10 el 20 de octubre puede haber recibido un archivo el día 8, y ese archivo sobrevive a la actualización: el parche cierra la puerta, no retira lo que ya entró. Es la objeción que hay que resolver antes de escribir al cliente «todo está corregido». El orden correcto es: parchear o neutralizar, luego buscar el compromiso (archivos, registros, cuentas, secretos), luego entregar una prueba fechada.
Hay un segundo obstáculo, más corriente: sin inventario central, nadie sabe qué clientes llevan el plugin. Un sitio Bricks entregado hace dos años y alojado con otro proveedor no aparece en ninguna alerta. El inventario va, por tanto, primero, y sirve para todas las fallas de plugin futuras.
Inventariar el parque con wp-cli
Probar un sitio cada vez
cd /home/client/public_htmlwp plugin is-installed bricksforge && wp plugin get bricksforge --field=versionwp plugin list --fields=name,version,update
El primer comando responde con su código de salida, el segundo muestra la versión, el tercero lista todos los plugins con su estado de actualización. La ruta es un ejemplo: adáptela a su proveedor.Encontrar todos los sitios de un servidor
find /home -name wp-config.php -not -path '*/wp-content/*'
Cadawp-config.phpseñala una instalación. El filtro descarta las copias guardadas en temas o copias de seguridad; revise la lista, una subcarpeta de pruebas olvidada también cuenta.Recorrer todas las instalaciones
find /home -name wp-config.php -not -path '*/wp-content/*' -print0 | while IFS= read -r -d '' f; do d=$(dirname "$f"); echo "$d $(sudo -u "$(stat -c %U "$d")" wp --path="$d" --skip-plugins --skip-themes plugin get bricksforge --field=version 2>/dev/null)"; done
Cada línea muestra la carpeta y la versión, o nada si el plugin no está. Las opciones--skip-plugins --skip-themesevitan cargar código potencialmente trampa durante la auditoría.Elegir el usuario con cuidado
Ejecute wp-cli con el usuario propietario del sitio, como en el bucle anterior.
--allow-rootfunciona, pero crea archivos de root dentro del sitio y ejecuta el código del sitio con plenos derechos: resérvelo para cuando no haya otra opción.Registrar el resultado en una tabla
Una fila por instalación: cliente, proveedor, ruta, versión encontrada, fecha y hora de la lectura. Añada una columna «visitado desde el 7 de octubre» que rellenará en la etapa siguiente. Esta tabla pasa a ser la pieza central del expediente entregado a los clientes.
Completar los sitios fuera de su servidor
Para un sitio alojado en otro lugar, pida un acceso temporal o una exportación de
wp plugin list --fields=name,version,update. Un sitio que no puede consultar permanece en la tabla con la mención «no verificado», no ausente.
Priorizar y fijar la ventana de auditoría retroactiva
Trate primero lo que está a la vez expuesto y explotado: un sitio con Bricksforge en 3.1.8.9 o inferior, formularios Pro Forms públicos, en producción. Después los sitios de pruebas y copias de trabajo, y luego aquellos donde el plugin está instalado sin estar activo. Un plugin inactivo merece una decisión: eliminarlo es más seguro que dejarlo envejecer.
La ventana retroactiva empieza el 7 de octubre de 2026 a las 21:47 UTC, primera señal publicada por Patchstack. Convierta esa hora a la zona horaria de sus registros antes de filtrar. Lo esencial: si sus registros no llegan hasta esa fecha, la ausencia de rastro no prueba nada. Anote la fecha de la línea más antigua disponible, pues limita lo que puede afirmar.
Actualizar, o neutralizar mientras tanto
Cuando la actualización es posible, wp plugin update bricksforge basta para una instalación que recibe las versiones con normalidad; según la licencia, el sitio puede exigir pasar por su panel o por el archivo del editor. Compruebe después con wp plugin get bricksforge --field=version: el resultado debe ser 3.1.8.10 o posterior.
Cuando aún no es posible, existen tres medidas provisionales, ninguna sustituye la corrección. Desactivar el plugin con wp plugin deactivate bricksforge corta la ruta, a costa de los formularios del sitio: avise al cliente. Prohibir la ejecución de PHP en uploads/ quita valor a un archivo depositado: en nginx, location ~* ^/wp-content/uploads/.*\.(php|php[0-9]|phtml|pht|phps)$ { deny all; } colocado antes del bloque PHP general; en Apache, un .htaccess en uploads/ con <FilesMatch "\.(php|php[0-9]|phtml|pht|phps)$"> Require all denied </FilesMatch>. Por último, un límite de tasa en /wp-json/bricksforge/v1/form_submit frena las ráfagas, y la regla RapidMitigate de Patchstack bloquea el tráfico de ataque para quien usa ese servicio. Estas medidas reducen el riesgo, no corrigen la falla.
Buscar archivos depositados y rastros de acceso
Buscar archivos PHP en uploads
find wp-content/uploads -type f \( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.pht' -o -iname '*.phps' \) -ls
Una carpetauploads/sana no contiene PHP ejecutable. Unindex.phpde unos pocos bytes, simple comentario, es habitual e inofensivo; lea cualquier otro archivo antes de juzgarlo.Apuntar a los objetivos citados por Patchstack
ls -la wp-content/uploads/bricksforge/tmp/find wp-content/uploads -name 'login_admin_*.php' -lsfind wp-content/uploads -type f -newermt '2026-10-07' -ls
Los dos primeros comandos apuntan a las ubicaciones y al nombre de archivo del aviso; el tercero lista todo lo escrito enuploads/desde el 7 de octubre, para detectar una variante.Revisar los registros de nginx
zgrep -h -i -E 'bricksforge/v1/form_submit|bricksforge_(form_submit|regenerate_nonce)' /var/log/nginx/access.log*zgreplee igual los archivos comprimidos y los de texto plano: la rotación gzip queda cubierta por el comodín. Conserve la fecha de cada línea y compárela con la ventana retroactiva.Revisar los registros de Apache y cPanel
zgrep -h -i -E 'bricksforge/v1/form_submit|bricksforge_(form_submit|regenerate_nonce)' /var/log/apache2/*access*.log* /var/log/httpd/*access*log* /usr/local/apache/domlogs/*
Las carpetas varían:/var/log/apache2/en Debian y Ubuntu,/var/log/httpd/en RHEL y AlmaLinux,/usr/local/apache/domlogs/en un servidor cPanel. Las rutas ausentes producen un error sin importancia.Buscar el acceso a archivos depositados
zgrep -h -i -E 'login_admin_[^ ]*\.php|/uploads/[^ ]*\.(php[0-9]?|phtml|pht)|%2e(php|phtml)' /var/log/nginx/access.log*
Una solicitud, sobre todo un GET con éxito, a un archivo PHP bajouploads/significa que un archivo pudo ejecutarse. Las variantes de mayúsculas y codificación se cubren aquí, en los registros, no en el disco.Contar los orígenes y registrar
zgrep -h 'POST /wp-admin/admin-ajax.php' /var/log/nginx/access.log* | awk '{print $1}' | sort | uniq -c | sort -rn | head
Este comando clasifica las direcciones por número de POST aadmin-ajax.php. Registre el resultado, aunque esté vacío, con la fecha más antigua de registro leída.
Lo que los registros no muestran
La acción AJAX suele viajar en el cuerpo del POST, que el registro de acceso no guarda: buscar bricksforge_form_submit puede no encontrar nada aunque la llamada ocurriera. En ese caso, busque un volumen anormal de POST a admin-ajax.php o a la ruta REST, y contrástelo con el estado del disco. Esta guía describe tareas de administración; se ofrece tal cual, sin soporte por nuestra parte.
Un archivo encontrado: el sitio ya no se considera sano
La presencia de un archivo depositado implica ejecución de código en el servidor con los derechos de la cuenta del sitio. Borrar solo el archivo no basta: pudo servir para crear una cuenta, leer wp-config.php o dejar una segunda puerta. Aísle el sitio, conserve una copia del archivo para analizarlo y restaure desde una copia de seguridad anterior al 7 de octubre de 2026 en lugar de limpiar a mano.
Tras la restauración, actualice Bricksforge antes de volver a poner el sitio en línea; si no, la misma solicitud vuelve a empezar. Si no existe una copia sana, reconstruya a partir del código fuente y de la exportación del contenido, y trate cualquier extracción de la base de datos como sospechosa.
Secretos y cuentas a renovar tras un compromiso
- Sales y claves de
wp-config.php—wp config shuffle-saltslas regenera e invalida las sesiones abiertas, incluida la de un intruso. - Contraseña de la base de datos — cámbiela en el servidor MySQL o MariaDB y luego en
wp-config.php, sin esperar. - Claves API y tokens — pagos, correo transaccional, mapas, servicios de terceros declarados en el sitio o en la base.
- Credenciales SMTP — una cuenta de correo legible en la configuración sirve enseguida para envíos fraudulentos.
- Contraseñas de administradores —
wp user reset-password <ID>para cada uno, y una contraseña única por persona. - Cuentas de WordPress desconocidas —
wp user list --fields=ID,user_login,role,user_registered --orderby=user_registered --order=DESCrevela las creaciones recientes. - Persistencias —
wp cron event list, la carpetawp-content/mu-plugins/y los plugins o temas que no son suyos.
La prueba fechada que se entrega al cliente
Un cliente que lee «actualizado» no sabe qué verificó usted. Entregue una ficha de una página por sitio: fecha y hora de la auditoría, versión antes y después, resultado de las búsquedas de archivos, período cubierto por los registros con la fecha de la línea más antigua leída, acciones realizadas (restauración, rotación, cuentas eliminadas) y lo que no pudo comprobarse. Incluir los límites protege tanto como los resultados.
Esta ficha es también su protección si un compromiso aparece más tarde: fecha lo que sabía y lo que hizo. Conserve la tabla de inventario y las salidas en bruto de los comandos junto con la ficha.
Repetir el procedimiento ante la próxima falla de plugin
Cinco tiempos, válidos para cualquier plugin. Inventariar: plugin, versión, sitio, cliente, proveedor. Priorizar: primero lo expuesto y explotado. Fijar la ventana retroactiva a partir de la primera señal publicada. Neutralizar o actualizar, y luego buscar archivos, rastros de acceso, cuentas y secretos, en ese orden. Entregar la prueba fechada. Solo cambian el comando de inventario y los patrones de búsqueda, que los aporta el aviso del editor o de Patchstack.
Un parque disperso entre varios proveedores hace lenta cada etapa. La cuenta de reventa reúne sus sitios en una sola cuenta, con un punto de acceso por cliente; el acceso SSH y wp-cli depende del plan, compruébelo antes. Usted conserva la relación con el cliente, nosotros mantenemos la infraestructura.
La documentación oficial
Aviso de Patchstack sobre CVE-2026-85097: https://patchstack.com/articles/critical-unauthenticated-arbitrary-file-upload-vulnerability-exploited-in-bricksforge-plugin/
Artículo de SecurityWeek: https://www.securityweek.com/bricksforge-wordpress-plugin-vulnerability-exploited-in-the-wild/
Comandos wp plugin: https://developer.wordpress.org/cli/commands/plugin/
Comando wp config shuffle-salts: https://developer.wordpress.org/cli/commands/config/shuffle-salts/
Directiva location de nginx: https://nginx.org/en/docs/http/ngx_http_core_module.html#location