Zero-day en GeoServer: inyección SQL en jsonArrayContains permite ejecución remota de código
En resumen
Lo más preocupante de este caso es que la vulnerabilidad es una regresión de CVE-2023-25158, una falla similar parchada en febrero de 2023. Que la misma clase de bug vuelva a aparecer tres años después en el mismo proyecto sugiere un problema sistémico en cómo el código CQL se traduce a SQL para PostGIS. Este artículo desglosa la vulnerabilidad, la cadena de explotación y las medidas defensivas que cualquier organización que ejecute GeoServer en producción debe aplicar de inmediato.
¿Qué es GeoServer y por qué importa?
GeoServer es una plataforma open-source escrita en Java que implementa los estándares del Open Geospatial Consortium (OGC) para servir datos geoespaciales a través de protocolos como WMS (Web Map Service), WFS (Web Feature Service) y WCS (Web Coverage Service). Es el servidor de mapas más usado en el mundo open-source y está presente en infraestructuras que van desde agencias gubernamentales hasta empresas de logística, pasando por organizaciones de gestión ambiental y proveedores de servicios cartográficos.
Para los equipos DevSecOps, GeoServer es un componente que a menudo queda fuera del radar porque:
- Lo despliega un equipo de GIS o de ingeniería de datos, no el equipo de seguridad. - Sus CVEs son publicados en bases de datos geoespaciales, no siempre en NVD. - Su superficie de ataque incluye protocolos WFS/WMS que muchos firewalls no inspeccionan a profundidad. - Los servidores GeoServer suelen estar expuestos en producción para servir mapas a usuarios externos.
Esa combinación de baja visibilidad y alta exposición convierte a GeoServer en un objetivo recurrente. CVE-2024-36401 (CVSS 9.8) fue explotado en 2025 para convertir servidores comprometidos en botnets de DDoS, minería de criptomonedas y proxies residenciales. La vulnerabilidad de 2026 sigue el mismo patrón: exposición amplia, explotación rápida, impacto operacional significativo.
La vulnerabilidad: jsonArrayContains sin escape
El detalle técnico del bug fue publicado por Hadrian en su blog "Here be dragons: GeoServer pre-auth SQL injection to RCE". El resumen del problema:
> "An attacker-controlled value is interpolated directly into a PostgreSQL jsonb_path_exists() expression without escaping."
El camino técnico es el siguiente. Cuando GeoServer recibe una solicitud WFS o WMS que incluye un filtro CQL (Common Query Language) o CQL2, el sistema traduce ese filtro a SQL para ejecutarlo contra el datastore de PostGIS. La función específica involucrada es `jsonArrayContains`, que PostGIS expone como extensión sobre el motor PostgreSQL.
La implementación vulnerable de GeoServer en el paquete `org.geotools:gt-jdbc-postgis` toma el valor del filtro CQL controlado por el atacante y lo inserta directamente en una llamada a `jsonb_path_exists()` sin escapado. Esa función PostgreSQL evalúa expresiones JSON path sobre documentos JSONB, y permite inyectar lógica arbitraria si el input no es validado.
El paquete Maven afectado:
- `org.geotools:gt-jdbc-postgis` versión 35.0 → arreglado en 35.1 - `org.geotools:gt-jdbc-postgis` versión 34.0 o superior → arreglado en 34.5 - `org.geotools:gt-jdbc-postgis` versión 33.1 o superior → arreglado en 33.6
La vulnerabilidad requiere PostGIS 12 o superior con un campo String o JSON. Sin PostGIS 12+ la función `jsonArrayContains` no está disponible, así que la vulnerabilidad no es explotable.
De SQL injection a RCE: la cadena completa
La inyección SQL por sí misma es grave, pero el verdadero riesgo es la conversión a ejecución remota de código. Hadrian publicó el camino exacto.
El WFS 1.0 de GeoServer permite, en ciertas configuraciones, ejecutar una segunda declaración SQL al nivel superior de la consulta. Combinado con la inyección SQL en `jsonArrayContains`, eso permite:
1. Inyectar una declaración SQL arbitraria que PostGIS ejecuta con los privilegios del usuario de conexión. 2. Aprovechar funciones PostgreSQL que permiten escribir archivos en el sistema (si los privilegios lo permiten). 3. O usar técnicas de PostGIS para invocar funcionalidad que termine ejecutando código en el servidor GeoServer.
El camino específico hacia RCE depende de la configuración del servidor, pero en la mayoría de los casos implica:
- Conexión de PostGIS usando el usuario `postgres` o un superusuario equivalente. - Uso de funciones PostgreSQL `lo_export`, `COPY ... TO` o equivalentes para escribir archivos en disco. - Carga del archivo escrito como una extensión compartida de PostgreSQL que ejecute código arbitrario.
Si el usuario de PostGIS no tiene privilegios elevados, la cadena se detiene en SQL injection con impacto limitado. Pero la configuración por defecto en muchas instalaciones usa un usuario con privilegios suficientes para llegar a RCE.
La regresión de CVE-2023-25158
Lo más alarmante del caso es que esta vulnerabilidad es una regresión de CVE-2023-25158, parchada en febrero de 2023. La descripción de los mantenedores de GeoTools lo dice explícitamente:
> "The maintainers also noted that the vulnerability is a regression of CVE-2023-25158 (CVSS score: 9.8), another critical SQL injection vulnerability that was addressed alongside CVE-2023-25157 in February 2023."
Una regresión de severidad 9.8 tres años después del parche original indica un problema sistémico:
- Las pruebas de regresión no cubrieron este caso específico. - La refactorización del código CQL en versiones intermedias probablemente perdió la validación. - La cobertura de fuzzing contra entradas CQL malformadas es insuficiente.
Para los consumidores de GeoServer, esto es un patrón preocupante. No es la primera vez que la plataforma tiene una vulnerabilidad crítica de SQL injection; es al menos la segunda. La pregunta razonable para un equipo DevSecOps es: ¿qué más no estamos viendo en este código?
Cronología de la divulgación y explotación
La línea temporal muestra una reacción razonablemente rápida de los mantenedores pero una ventana de exposición significativa:
- **12 de agosto de 2026, 10:46 UTC**: @q1uf3ng publica el advisory inicial en X. - **Primeras horas**: watchTowr detecta los primeros intentos de explotación contra sistemas expuestos en internet. - **Primer día**: cientos de intentos confirmados provenientes de un pool pequeño de IPs. - **14 de agosto de 2026**: GeoServer publica parches en versiones 3.0.1, 2.28.5 y 2.27.6. - **Asignación de GHSA-mqjf-5f49-2fjh**: el advisory de GitHub se publica con CVSS 9.8.
La ventana entre divulgación pública y parche fue de 48 horas. Para una vulnerabilidad de esta severidad, 48 horas es suficiente para que múltiples actores escaneen internet, identifiquen objetivos vulnerables y exploten exitosamente.
Comportamiento observado de los atacantes
Jake Knott, investigador principal de seguridad en watchTowr, confirmó el patrón de explotación:
> "Currently, we're seeing attackers probe to identify vulnerable systems across the internet, triggering errors and not proceeding further. However, this is unlikely to remain the case for long: GeoServer has a track record of being targeted and exploited at scale, with multiple vulnerabilities listed in CISA's Known Exploited Vulnerabilities catalog. More importantly, under certain configurations, this latest vulnerability could ultimately lead to remote code execution."
Los atacantes están en fase de reconocimiento, no de explotación masiva todavía. Eso significa que la ventana para parchear antes de la explotación masiva está abierta, pero se está cerrando. El momento de parchear es ahora.
Mitigación inmediata
**1. Aplicar el parche.** Si ejecutas GeoServer, actualiza a una de las versiones parcheadas:
- GeoServer 3.0.1 o superior - GeoServer 2.28.5 o superior - GeoServer 2.27.6 o superior
Verifica tu versión actual:
```bash # Verificar versión de GeoServer # En la consola web: About > Build Information # O desde la línea de comandos del servidor: unzip -p /opt/geoserver/webapps/geoserver/WEB-INF/lib/gt-jdbc-postgis-*.jar META-INF/MANIFEST.MF | grep Implementation-Version ```
**2. Identificar instancias expuestas.** Escanea tu infraestructura con Shodan o Censys para detectar instancias GeoServer con puerto 8080 (o el configurado) accesible desde internet. Cualquier instancia expuesta sin necesidad de negocio es candidata a aislamiento inmediato.
**3. Configurar autenticación en endpoints WFS.** Aunque GeoServer permite acceso anónimo por defecto para muchas operaciones, los endpoints WFS que ejecutan queries CQL deberían requerir autenticación cuando sea posible. Verifica la configuración en `Security > Data > Security settings`.
**4. WAF con reglas específicas.** Despliega reglas de WAF para bloquear solicitudes WFS con patrones CQL sospechosos. Las funciones que no deberían aparecer en queries externos (`jsonArrayContains`, `ST_AsText`, `lo_export`, etc.) deben estar en la lista de denegación.
```nginx # Ejemplo de regla nginx para WAF básico location /geoserver/ows { if ($args ~ "jsonArrayContains") { return 403; } if ($args ~ "lo_export|copy.*to|pg_read_file") { return 403; } # ... resto de la configuración del proxy } ```
**5. Auditoría del usuario PostGIS.** Verifica qué usuario se usa para conectar GeoServer a PostGIS. Si es un superusuario, cambiarlo a un usuario con privilegios mínimos. Eso reduce drásticamente el alcance de cualquier inyección SQL.
```sql -- Crear usuario dedicado con privilegios mínimos CREATE USER geoserver_user WITH PASSWORD 'secure_password'; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO geoserver_user; GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO geoserver_user; ```
**6. Segmentación de red.** Las instancias GeoServer no deberían ser accesibles directamente desde internet a menos que sea absolutamente necesario. Un proxy reverso con autenticación y rate limiting es preferible a exposición directa.
**7. Telemetría de queries CQL.** Activar logging detallado de queries CQL ejecutadas y centralizar en SIEM. Queries con funciones inesperadas o caracteres de escape deben generar alerta.
Implicaciones regulatorias
Para organizaciones sujetas a NIS2, una instancia GeoServer comprometida puede tener implicaciones serias. Si el servidor almacena o sirve datos geoespaciales que incluyen infraestructura crítica (redes eléctricas, instalaciones militares, datos de biodiversidad sensible), el compromiso puede escalar a incidente reportable.
Bajo GDPR, si los datos servidos por GeoServer incluyen información personal (direcciones de instalaciones, datos de empleados geolocalizados), el compromiso es una brecha de datos personales con obligaciones de notificación dentro de 72 horas.
Para el sector público, las instancias GeoServer comprometidas que sirven datos cartográficos oficiales pueden afectar la integridad de la información pública. En algunos casos esto activa obligaciones específicas de comunicación a la ciudadanía.
Comparación con CVE-2024-36401
CVE-2024-36401 fue una vulnerabilidad de evaluación de propiedades en GeoTools que también permitía RCE. Fue explotada en 2025 para:
- Construir botnets de DDoS usando la capacidad de red de los servidores comprometidos. - Instalar mineros de criptomonedas en infraestructura de procesamiento de mapas. - Convertir servidores en proxies residenciales para anonimizar otras actividades maliciosas.
El patrón se repite: GeoServer como objetivo prioritario para campañas commodity porque sus instancias suelen estar:
- Expuestas en internet. - Mantenidas por equipos con baja prioridad de seguridad. - En infraestructura con capacidad de cómputo significativa (útil para minería). - Con datos que pueden ser exfiltrados y monetizados.
La vulnerabilidad de 2026 sigue el mismo perfil. Las organizaciones que no parchearon GeoServer después de CVE-2024-36401 deberían estar en alerta roja.
Plan de respuesta para compromisos confirmados
Si detectas intentos de explotación o compromiso confirmado en una instancia GeoServer:
1. **Aislar la instancia inmediatamente.** Desconectar de la red corporativa para prevenir movimiento lateral. 2. **Capturar imagen forense.** Snapshot del sistema antes de cualquier cambio para análisis posterior. 3. **Auditar logs de PostGIS.** Buscar queries con `jsonArrayContains` o patrones de inyección. 4. **Revisar archivos del sistema.** Buscar archivos nuevos en `/tmp`, `/var/tmp`, y directorios de extensiones de PostgreSQL. 5. **Rotar credenciales.** Cambiar todas las credenciales de PostGIS, certificados TLS, y cualquier secreto almacenado. 6. **Reinstalar desde cero.** Después de capturar evidencia, reinstalar la instancia desde backups limpios verificados. 7. **Notificar al equipo legal y de cumplimiento.** Si hay datos personales involucrados, activar protocolo de notificación a autoridades.
Lista de comprobación inmediata
- [ ] Versión actual de GeoServer verificada contra advisory GHSA-mqjf-5f49-2fjh. - [ ] Plan de actualización a 3.0.1, 2.28.5 o 2.27.6 según línea. - [ ] Escaneo de exposición externa completado. - [ ] Reglas de WAF específicas para endpoints OWS desplegadas. - [ ] Usuario PostGIS verificado con privilegios mínimos. - [ ] Telemetría de queries CQL centralizada en SIEM. - [ ] Plan de respuesta a incidentes específico para GeoServer. - [ ] Backups verificados y probados para restauración limpia.
Llamado a la acción
Si tu organización ejecuta GeoServer en producción, la ventana de remediación es de horas, no días. Parchea ahora, despliega WAF con reglas para OWS endpoints, y verifica que el resto de tu infraestructura geoespacial no esté en la misma situación.
Cada semana publicamos análisis técnicos de vulnerabilidades críticas con contexto accionable para equipos DevSecOps. Síguenos en X, Instagram, LinkedIn y YouTube de X-Ops, y en X, Instagram y LinkedIn de Hacker Dreams, para no perderte el próximo análisis.
---
*Fuentes: advisory GHSA-mqjf-5f49-2fjh en GitHub (github.com/geotools/geotools/security/advisories/GHSA-mqjf-5f49-2fjh), análisis técnico de Hadrian (hadrian.io/blog/here-be-dragons-geoserver-pre-auth-sql-injection-to-rce), reporte de watchTowr, reporte original de The Hacker News, advisory inicial del investigador @q1uf3ng en X.*