¡Vaya! Un fallo de inyección SQL obligó a aplicar un parche de emergencia en el núcleo de WordPress la semana pasada.
El 17 de julio, WordPress lanzó una versión de emergencia para corregir un fallo de ejecución remota de código sin autenticación en el núcleo, al que se puede acceder mediante una inyección SQL que un atacante anónimo puede aprovechar en una instalación predeterminada. WordPress.org llegó incluso a activar las actualizaciones automáticas obligatorias debido a la gravedad del problema. Searchlight Cyber, que informó del fallo, estima que más de 500 millones de sitios web utilizan WordPress. Si te ves afectado, actualiza a la versión 7.0.2, y a la 6.9.5 si utilizas la rama anterior.
La inyección SQL, también conocida como SQLi, es una vulnerabilidad antigua cuya solución es sencilla, por lo que la gente da por hecho que ya no existe. Pero, como se nos acaba de recordar, no es así.

Inyección SQL: desde sus humildes comienzos hasta la actualidad
La inyección SQL y sus soluciones forman parte de las clases de Introducción a la Informática. Recuerdo haber estudiado la inyección de comandos en la universidad hace más de una década y, sinceramente, es la única vulnerabilidad relacionada con aplicaciones que recuerdo que nos enseñaran (creo que pasaron a otros temas después de tratarla, o quizá yo no presté atención a partir de ahí).
La inyección SQL fue descrita públicamente en 1998 por el investigador conocido como «rainforest puppy». La solución que resuelve la mayoría de los problemas de inyección SQL —las sentencias preparadas— se descubrió aproximadamente un año después. Esta solución es más antigua que muchos de los ingenieros de la empresa. Utiliza consultas parametrizadas y trata las entradas de los usuarios como datos. Sin embargo, a pesar de que existe una solución, las inyecciones SQL siguen produciéndose.
Según los datos de la base de datos de avisos de GitHub, filtrando los avisos por CWE y contabilizándolos por año:
El número de avisos sobre inyecciones SQL aumentó cada año natural entre 2023 y 2025, pasando de 2.096 a 2.850. Las tres clases de inyección más antiguas —la inyección SQL, la inyección de comandos y el recorrido de rutas— siguen representando, en conjunto, más de una de cada diez de todas las incidencias notificadas.
OWASP ha bajado la inyección del tercer al quinto puesto en su Top 10 de 2025, pero no porque se hayan solucionado los problemas. La categoría general de inyección sigue registrando más CVE notificados que cualquier otra, con más de 60 000 casos. De ellos, solo la inyección SQL sumaba más de 14 000. En los análisis realizados por Mackenzie en repositorios de código cerrado, el 20 % de los proyectos presentaba al menos un fallo de inyección SQL en su primer análisis.
¿Por qué la inyección SQL se resiste a desaparecer?
En primer lugar, para dejarlo claro desde el principio, la gente comete errores al escribir código. Es algo que ocurre. Por eso, de vez en cuando, se nos escapará algún SQLi. Pero los sistemas modernos que deberían ayudarnos no lo hacen al cien por cien de las veces, e incluso pueden llevarnos a cometer otros errores.
Por ejemplo, los marcos de trabajo más recientes cuentan con métodos que ayudan a prevenir la inyección SQL. Los ORM como Django, Hibernate y ActiveRecord parametrizan por defecto, lo que lleva a muchos equipos a creer que el problema está resuelto. Pero si alguien recurre a una consulta sin procesar o utiliza un método inseguro, la protección desaparece.
El CVE-2024-42005 de Django es un ejemplo. Dos de los propios métodos de consulta de Django, utilizados para leer campos de una columna JSON, insertaban directamente en la consulta SQL los nombres de campo que se les pasaban sin filtrarlos, por lo que un atacante que controlara un nombre podría controlar parte de la consulta a través de un método que los equipos consideraban seguro.
Por otro lado, el código muy antiguo también supone un problema, ya que el código heredado ha ido transmitiendo estos fallos durante décadas. Los equipos se apoyan en un WAF y dan por hecho (o rezan para que) este detecte todo. Aunque la solución existe desde hace más de 25 años, aplicarla en cada consulta, cada punto final y cada rincón del código heredado, en todo momento, supone una enorme cantidad de trabajo tedioso que nunca se ha completado en su totalidad en todas las bases de código. Tal y como lo plantea Mackenzie Jackson, nuestro director técnico de campo, esto dejó de ser un problema técnico para convertirse en uno de cultura, procesos y formación.
Y, por supuesto, la IA.
La IA también escribe SLQi
La esperanza obvia es que los asistentes de programación basados en IA, entrenados con ejemplos de décadas, dejen de reproducir un error de 1998. Pero, como sabemos, la IA no escribe código perfecto.

Podemos analizar esto de forma cuantitativa. El estudio «Asleep at the Keyboard» de 2021, realizado por la NYU y Cornell, generó 1.689 programas a partir de GitHub Copilot en escenarios comunes de vulnerabilidades y descubrió que alrededor del 40 % eran vulnerables, siendo la inyección SQL y la inyección de comandos las más frecuentes. La propia prueba de Mackenzie se sitúa en el mismo rango. Al ejecutar una misma solicitud en ChatGPT unos cientos de veces, alrededor del 12 % de los resultados eran susceptibles de inyección, una cifra cercana a la tasa observada en el software de código abierto.
¿Pero por qué? Los modelos aprenden del código público que presenta estos fallos, por lo que los reproducen con una frecuencia similar. La IA gestiona mejor las inyecciones SQL que los errores que dependen en gran medida del contexto, como el cross-site scripting, en los que, según el mismo informe, la mayoría de los resultados resultaron inseguros. La IA sigue mejorando, por lo que estas cifras quedarán desactualizadas en seis meses, pero cabe esperar que la IA siga escribiendo esto de forma accidental, tal y como lo hacemos nosotros.
Y ahora, cada vez son más los programadores que se guían más por la intuición y menos por la formación técnica. Son menos propensos a detectar las inyecciones SQL (si es que saben siquiera que deben buscarlas), por lo que puede incorporarse más código al repositorio de la empresa sin que haya ojos expertos que se aseguren de que se tiene en cuenta este problema.
Por eso es imprescindible contar con un mecanismo de seguridad
Aunque lo hagas todo bien, como utilizar consultas parametrizadas en todas partes, aplicar listas de permitidos en cada entrada, etc., seguirás necesitando protección en tiempo de ejecución. La sanitización perfecta en todos los puntos de acceso, de forma permanente, no existe. Un ataque SQLi podría incluso producirse en una dependencia vulnerable que no controlas (o, por ejemplo, en el sitio predeterminado de un proveedor de alojamiento web), lo cual escapa a cualquier control razonable por tu parte.
Aikido Zen es un firewall integrado en la aplicación se ejecuta dentro de esta y supervisa los datos introducidos por el usuario a medida que se dirigen hacia un destino de datos, como una consulta a una base de datos o la lectura de un archivo.
Cuando la carga útil de un ataque está a punto de llegar a uno de estos lugares, Zen la bloquea al instante, con suficiente contexto de la aplicación como para distinguir un ataque de una cadena de búsqueda que, por casualidad, se parezca a uno.
También cubre las vulnerabilidades que se introducen a través de las dependencias, donde tus propios estándares de programación no llegan. Considéralo como un respaldo en tiempo de ejecución para cuando la programación segura no sea suficiente, lo cual, en la práctica, siempre ocurre. Zen es un RASP, que detecta entradas peligrosas a nivel de código. Esto difiere de un WAF, que bloquea entradas sospechosas a nivel de red, lo cual es menos preciso, por lo que tiende a bloquear en exceso. Abordo este tema con mucho más detalle en nuestra entrada sobre WAF, RASP y ADR.
Un firewall integrado en la aplicación Zen, actúa de barrera entre wp2shell y un sitio de WordPress sin parches. Zen está diseñado para bloquear la inyección SQL en la que se basa esta vulnerabilidad, por lo que un sitio que estuviera a la espera de la actualización seguía contando con una defensa mientras se implementaba el parche.
Detecta las inyecciones SQL en tu rama de desarrollo
El tiempo de ejecución es la red de seguridad, pero la prevención es, por supuesto, la mejor opción. Lo ideal sería detectar y eliminar todas las inyecciones SQL del código.
El análisis estático, como SAST muchos casos de inyección SQL, sobre todo los más sencillos, en los que la entrada se introduce directamente en una consulta sin una instrucción parametrizada. En este caso concreto, no lo habría detectado. El núcleo de WordPress es uno de los programas más analizados que existen, y este error no se detectó. En este caso, la inyección solo se vuelve explotable cuando una solicitud por lotes malformada desajusta el sistema interno de contabilidad de WordPress, de modo que el valor llega a la base de datos a través de una ruta que omite la limpieza. Se trata de una interacción entre solicitudes que un escáner estático no es capaz de analizar. Para detectar esta vulnerabilidad se utilizó un modelo de vanguardia que ejecutó cuatro agentes durante seis horas.
La detección diaria es tarea de tu escáner. Las vulnerabilidades ocultas, que dependen de la lógica, requieren cada vez más el uso de la IA para detectarlas antes de que lo haga otra persona; tal es el caso de pentesting de IA su aplicación a tu propio código, del mismo modo que este investigador lo hizo con WordPress. Aikido ofrece pentesting continuo Aikido Infinite, lo que puede ayudarte a comprobar periódicamente si hay alguna nueva vulnerabilidad SQLi que pueda pasar desapercibida en la revisión del código.
El pequeño Bobby Tables sigue vivo y goza de buena salud. Tómatelo en serio y protege tu código, incluso las partes más aburridas.

