Auditoría de seguridad WordPress de una pequeña empresa
Un sitio WordPress de una pequeña empresa llegó a auditoría de seguridad, y los hallazgos eran del tipo corriente que deja un sitio a un escaneo automático de distancia del compromiso. El page builder, Elementor, estaba fijado en la versión 3.11.1, por debajo de los parches de cinco CVE registradas en el NVD, entre ellas SQL injection y cross-site scripting. Contact Form 7 corría en 5.8, expuesto a CVE-2023-6449, una subida arbitraria de archivos. Nada exótico, solo plugins desactualizados, la forma dominante en que se comprometen los sitios WordPress.
Lo incómodo es lo normal que resulta. El sitio funcionaba. Se veía bien. El propietario no tenía motivo para sospechar, porque los plugins desactualizados no dan síntomas hasta que se explotan. La auditoría existía para encontrar el hueco antes de que lo hiciera otro.
Por qué los plugins desactualizados de WordPress son un riesgo
Un plugin es seguro mientras recibe parches. En el momento en que una vulnerabilidad se publica como CVE y no has actualizado, el exploit es conocimiento público y tu versión instalada se convierte en un objetivo nombrado para escáneres automáticos. Los ataques a WordPress son en su mayoría ciegos y automáticos. Los bots barren la red en busca de versiones conocidamente vulnerables de plugins populares, así que ejecutar un Elementor o Contact Form 7 antiguo no es un riesgo abstracto. Está anunciado.
En este sitio:
- Elementor 3.11.1 estaba por debajo de los parches de cinco CVE registradas en el NVD: SQL injection (CVE-2023-0329, corregida en la 3.12.2), falta de autorización (CVE-2023-33922, corregida en la 3.13.3), cross-site scripting (CVE-2023-47505) y autenticación incorrecta (CVE-2023-47504, la que el NVD califica de crítica, 9,8), ambas presentes hasta la 3.16.4, y una subida de archivos peligrosos (CVE-2023-48777, corregida en la 3.18.2). Las cinco estaban activas en producción.
- Contact Form 7 5.8 estaba expuesto a CVE-2023-6449, un fallo de subida arbitraria de archivos en el propio plugin (versiones hasta la 5.8.3 incluida) que permitía a un usuario autenticado con permisos de editor subir archivos arbitrarios. Por sí solo rara vez lleva a ejecutar código, pero encadenado con un segundo fallo, como una inclusión local de archivos, sí puede.
Ninguno de los dos plugins era raro. Ambos están en una parte enorme de los sitios WordPress. Por eso exactamente sus vulnerabilidades conocidas merecen el tiempo de un escáner. Patchstack, en el informe State of WordPress Security in 2026, mide la mediana de tiempo desde la divulgación pública de una vulnerabilidad de alto impacto hasta la explotación masiva en cinco horas. La ventana entre «la CVE es pública» y «un bot ya escanea tu versión» se cuenta en horas, no en semanas.
El mismo informe de Patchstack cuenta 11.334 vulnerabilidades nuevas en el ecosistema WordPress en 2025: el 91 por ciento en plugins, el 9 por ciento en temas y solo 6 en el núcleo de WordPress, todas de prioridad baja. Una auditoría que se queda en la versión del núcleo revisa la parte más pequeña de la superficie de ataque.
Los plugins abandonados empeoran el cuadro. Cuando el autor deja de publicar correcciones, una CVE solo se cierra quitando o sustituyendo la herramienta. Dejar un plugin muerto «por si acaso» en wp-content/plugins/ mantiene viva la superficie de ataque incluso tras desactivarlo, si los archivos siguen en disco y son alcanzables por rutas conocidas.
Cómo priorizar las CVE de plugins WordPress
El panel de WordPress muestra actualizaciones por orden alfabético o por fecha. El triaje de seguridad ordena de otra forma:
- Gravedad y clase de ataque. Subida de archivos, ejecución remota de código e inyección SQL van antes que un XSS que exige un admin autenticado.
- Privilegios necesarios. Un fallo no autenticado, o alcanzable como suscriptor/editor, tiene prioridad sobre uno que exige un administrador del que tienes uno y proteges con 2FA.
- Si la ruta de código vulnerable está en uso. Una CVE en una función opcional solo importa en sitios donde esa función es alcanzable. La auditoría comprueba si la función afectada se usa de verdad en el sitio, no solo si el plugin está instalado.
- Si existe un exploit público. Cuando un proof of concept circula en threat intel, el tiempo de respuesta se reduce a horas. Patchstack también señala que el 46 por ciento de las vulnerabilidades no tienen parche en el momento de la divulgación, así que a veces la única respuesta inmediata es desactivar la función o el plugin, no «pulsar Actualizar».
En el sitio de este caso, el triaje fue claro: primero Contact Form 7 (subida), luego Elementor (injection y XSS), después limpieza del resto de plugins sin CVE activa. El número de CVE y la fecha de publicación no sustituyen ese orden.
Cómo leer la puntuación CVSS de una CVE de plugin WordPress
Las bases de datos de vulnerabilidades asignan una puntuación base CVSS a casi todas las CVE. La especificación CVSS v3.1 de FIRST traduce el número a una calificación: 0,0 es None, de 0,1 a 3,9 Low, de 4,0 a 6,9 Medium, de 7,0 a 8,9 High y de 9,0 a 10,0 Critical. La puntuación se calcula con métricas como Attack Vector, Attack Complexity, Privileges Required y User Interaction, y el vector que aparece junto al número dice más sobre tu sitio que el propio número.
CVE-2023-6449 lo ilustra. La ficha del NVD muestra dos puntuaciones CVSS 3.1 para el mismo fallo:
| Quién puntúa | Vector | Puntuación |
|---|---|---|
| Wordfence (CNA) | AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H | 6,6 Medium |
| NVD | AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H | 7,2 High |
La única diferencia es Attack Complexity. Wordfence la calificó como High, que en la definición de FIRST significa que el éxito depende de condiciones fuera del control del atacante; el NVD la calificó como Low. Esa sola métrica mueve la calificación de Medium a High. Ambos coinciden en PR:H, privilegios altos, el nivel que FIRST describe como control significativo, por ejemplo derechos de administración. Para el triaje esa es la parte útil: en un sitio con una sola cuenta de editor protegida con doble factor, el riesgo práctico es menor que en uno donde una docena de accesos de editor se reparten entre plantilla, agencia y freelancers.
FIRST también recomienda a quien usa CVSS completar la puntuación base con las puntuaciones temporal y de entorno. La especificación CVSS v4.0, publicada el 1 de noviembre de 2023, señala que proveedores como los mantenedores de productos y el NVD suelen publicar solo puntuaciones base, etiquetadas como CVSS-B. La parte de entorno, cuánto está expuesta la función vulnerable en tu sitio concreto, sigue siendo trabajo del auditor.
Quién asigna el identificador CVE a una vulnerabilidad de plugin WordPress
Los identificadores CVE los asignan las CVE Numbering Authorities (CNA): fabricantes, investigadores, CERT y otras organizaciones a las que el programa CVE autoriza a asignar identificadores y publicar registros CVE dentro de su propio ámbito. Patchstack, Wordfence y WPScan figuran como CNA en esa lista de socios. El registro de CVE-2023-6449 en cve.org nombra a Wordfence como asignador: el identificador se reservó el 30 de noviembre de 2023 y se publicó el 1 de diciembre de 2023. El registro marca como afectadas las versiones de Contact Form 7 hasta la 5.8.3 incluida y enlaza como corrección el cambio de código entre la 5.8.3 y la 5.8.4. El NVD añade después su propio análisis, y de ahí sale la segunda puntuación de la tabla.
En una auditoría, el fabricante, la CNA y el NVD publican en momentos distintos y pueden puntuar distinto. Que un escáner muestre Medium y otro High para la misma versión de un plugin no es un conflicto que se resuelva eligiendo el número más bajo. La auditoría anota el identificador CVE, el rango de versiones afectadas según el registro y la primera versión corregida, y compara ese rango con la versión instalada de verdad.
Cómo actualizar plugins de WordPress con staging
El salto de Elementor de 3.11.1 a la línea 3.18+ no es solo un parche de seguridad. Cambia renderizadores, widgets y a menudo plantillas del tema hijo. Un formulario de contacto con un shortcode de subida antiguo puede, tras la actualización, devolver pantalla blanca o silenciar adjuntos. Por eso la reparación tras la auditoría fue así:
- Copia completa de archivos y base de datos a staging con el mismo PHP y las mismas constantes en
wp-config.php(sinWP_DEBUG_DISPLAYde producción). - Actualizar plugins con CVE en orden de triaje, luego pasada manual: portada, carrito o formulario de leads, pantalla de edición de Elementor, envío del formulario con adjunto.
- Comparar logs PHP y HTTP 500 antes de publicar en producción.
- En producción, el mismo par de versiones de plugins, smoke test corto y solo entonces eliminar plugins innecesarios.
Actualizar directamente en el sitio en vivo sin copia de seguridad convierte el parcheo de CVE en un segundo incidente: checkout caído o hero roto. El staging no es un lujo de agencia. Forma parte del proceso que también describe el hardening oficial de WordPress en la capa de mantenimiento, no solo en la de archivos.
Cómo activar las actualizaciones automáticas de plugins en WordPress
Las actualizaciones automáticas de plugins forman parte del núcleo desde WordPress 5.5. El anuncio del equipo de core indica que las actualizaciones automáticas de plugins y temas están desactivadas por defecto, así que no ocurre nada hasta que un administrador las activa plugin a plugin en la pantalla de plugins. El núcleo funciona al revés: según la documentación de actualización de WordPress, las instalaciones existentes reciben por defecto, de forma automática, las versiones menores del núcleo, que incluyen las de mantenimiento y seguridad.
La misma documentación enumera los interruptores que una auditoría debe buscar en wp-config.php y en el código:
define( 'AUTOMATIC_UPDATER_DISABLED', true );desactiva todo tipo de actualización automática, núcleo incluido. En un sitio sin rutina manual de actualizaciones, esta línea por sí sola explica cómo los plugins se quedan años atrás.WP_AUTO_UPDATE_COREconfalsedesactiva las actualizaciones del núcleo, con'minor'deja solo las menores y contruepermite también las mayores.add_filter( 'auto_update_plugin', '__return_true' );fuerza las actualizaciones automáticas de todos los plugins, y una función sobre el mismo filtro puede limitarlas a una lista de slugs.
Desde la línea de comandos, wp plugin auto-updates enable (WP-CLI 2.5.0 o posterior) las activa para un plugin, o para todos con --all.
Las actualizaciones automáticas no sustituyen la ruta de staging descrita arriba. Encajan en plugins pequeños de una sola función cuyas versiones rara vez cambian lo que se ve en el front-end. Los page builders, los plugins de formularios y todo lo ligado al checkout van por staging, porque un salto de varias versiones menores cambia plantillas. La auditoría anota qué plugin está en cada grupo, para que la decisión sea deliberada y no un valor por defecto.
Es suficiente un WAF para proteger WordPress
Un WAF (Cloudflare, Sucuri, reglas de hosting) y el parcheo virtual compran tiempo entre la divulgación de la CVE y el despliegue de la corrección. La documentación de Sucuri Website Firewall describe el bloqueo de patrones de petición conocidos, no la eliminación de código vulnerable del disco. Esa distinción importa cuando el dueño del sitio ha oído «tenemos firewall, así que estamos seguros».
El informe Patchstack State of WordPress Security in 2026 indica que los conjuntos típicos de hosting más WAF detienen alrededor del 12 por ciento de los ataques conocidos a WordPress. El resto esquiva firmas, usa una sesión autenticada, golpea un endpoint fuera de las reglas o ataca un plugin para el que aún no hay regla. Un WAF no:
- elimina un plugin abandonado de
wp-content/plugins/, - corrige la falta de nonce y
current_user_canen código propio, - sustituye el cotejo de versiones con la base de CVE,
- garantiza protección cuando el ataque pasa por un editor autenticado (como en CVE-2023-6449).
El arreglo sensato es WAF como primera línea más rutina de actualización como línea duradera. Solo WAF sin triaje ni staging deja exactamente el estado que encontramos: Elementor y formulario sin parche durante años porque «el firewall debería bastar».
Qué revisa una auditoría de seguridad WordPress
Una auditoría de seguridad es metódica, no ingeniosa. Su núcleo:
- Inventariar cada plugin y tema instalado y cotejar cada versión con sus CVE conocidas y la versión mínima segura. Eso sacó a la luz la exposición de Elementor y Contact Form 7 aquí.
- Triar las CVE encontradas por gravedad, privilegios y si la función está activa en producción.
- Probar código propio y del tema frente a los fundamentos de seguridad de WordPress: verificación de nonce y capacidades en acciones, entrada saneada antes de la base de datos, salida escapada antes de la página, endpoints que exigen autorización.
- Revisar la exposición a nivel de servidor:
xmlrpc.phpabierto, errores PHP en producción que filtran rutas, cabeceras de seguridad ausentes. - Revisar la política de actualización, staging y copias de seguridad, porque un sitio sin mantenimiento vuelve a este estado en meses.
- Valorar si el WAF ve de verdad las rutas de ataque de las CVE encontradas, o solo da sensación de cobertura.
El cotejo de versiones es la parte poco espectacular que más atrapa, porque la vulnerabilidad WordPress más común no es un zero-day ingenioso. Es un plugin popular tres versiones por detrás de su parche.
Cómo listar las versiones de plugins para una auditoría WordPress con WP-CLI
El inventario de versiones no necesita un escáner de pago para empezar. En un servidor con WP-CLI, wp plugin list muestra qué está instalado, qué versión hay disponible y si las actualizaciones automáticas están activas:
wp plugin list --fields=name,status,version,update_version,auto_update --format=csvCon --status=inactive la lista se reduce a los plugins desactivados, los archivos que siguen en disco aunque nadie los use. Para plugins del directorio de WordPress.org, los campos opcionales wporg_status y wporg_last_updated indican si el plugin sigue publicado y cuándo salió su última versión, la señal más rápida de abandono:
wp plugin list --fields=name,version,wporg_status,wporg_last_updatedEl CSV es la entrada del cotejo de CVE: cada par de nombre y versión se compara con los rangos de versiones afectadas de la base de vulnerabilidades que use la auditoría. Un segundo comando, wp plugin verify-checksums --all, compara los archivos de los plugins con las sumas de verificación que publica WordPress.org y detecta archivos modificados por un compromiso anterior. Solo puede verificar plugins para los que WordPress.org tiene sumas, así que los plugins comerciales distribuidos fuera del directorio necesitan una comprobación aparte.
Riesgos de seguridad de sitios WordPress hechos con IA
Esta auditoría trataba de plugins de terceros desactualizados, un patrón de abandono. Los despliegues asistidos por IA añaden una segunda capa. Instalan plugins rápido, a menudo sin rutina de actualización y staging, así que las versiones se quedan atrás de los parches aún más rápido. El código propio generado por IA suele nacer sin las comprobaciones de nonce, capacidades y saneamiento que WordPress espera, así que heredas a la vez el problema de plugins desactualizados y el de código generado.
Cómo corregir vulnerabilidades de plugins desactualizados
El orden de reparación sigue el riesgo, no la comodidad:
- Parchear o eliminar de inmediato los plugins con CVE activas, empezando por las rutas de subida e injection, tras prueba en staging.
- Eliminar plugins abandonados o ya innecesarios, reduciendo la superficie de forma permanente (archivos fuera del disco, no solo desactivación).
- Cerrar la exposición a nivel de servidor (
xmlrpc.php, visualización de errores en producción, cabeceras ausentes). - Situar el WAF como buffer de tiempo, no como sustituto de las actualizaciones.
- Implantar una rutina real de actualización, staging y copias de seguridad para que el sitio no vuelva a cinco CVE activas en un año.
Si necesitas pasar de una lista de CVE a un plan de reparación en un sitio en vivo, empieza por la auditoría de seguridad WordPress.
Glosario
- CVE - identificador Common Vulnerabilities and Exposures, entrada pública de catálogo de una vulnerabilidad conocida concreta.
- Triaje de CVE - ordenar fallos por gravedad, privilegios y exposición de la función, no por el orden de la pantalla de actualizaciones.
- SQL injection - ataque que introduce comandos de base de datos a través de entrada no saneada.
- Stored cross-site scripting - script malicioso guardado en el sitio y servido a otros usuarios.
- WAF - cortafuegos de aplicación web que filtra peticiones HTTP; reduce ventanas de ataque, no elimina código vulnerable.
- Verificación de nonce / capacidades - mecanismos de WordPress que confirman que la petición es intencionada y que el usuario puede hacerla.
- CVSS - Common Vulnerability Scoring System, el estándar de FIRST para puntuar la gravedad de una vulnerabilidad de 0,0 a 10,0.
- CNA - CVE Numbering Authority, organización autorizada por el programa CVE para asignar identificadores CVE y publicar registros CVE.
Conclusión
Un sitio WordPress no tiene que ser interesante para ser atacado. Tiene que ejecutar una versión conocida como vulnerable de un plugin popular, lo que describe una gran parte de los sitios que no se han auditado. El riesgo dominante también es el más aburrido de arreglar: coteja cada versión de plugin con sus CVE, haz triaje, parchea por staging, no confíes solo en el WAF y elimina lo que ya no usas. El sitio de esta auditoría estaba a un escaneo de problemas y no lo sabía. La mayoría de sitios en esa situación tampoco lo saben.







