Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
rewrite-cve-2026-22732 — Receta de OpenRewrite que detecta y corrige la supresión de cabeceras de Spring Security (CVE-2026-22732) identificando el uso incorrecto de la cabecera Content-Length y generando una configuración de escritura anticipada de cabeceras. | Kitploit
Herramientas/GitHubGitHub/moderneinc/rewrite-cve-2026-22732
Análisis EstáticoAnálisis de VulnerabilidadesAnálisis de CódigoSeguridad WebDevSecOps
GitHubmoderneinc/rewrite-cve-2026-22732

rewrite-cve-2026-22732

Receta de OpenRewrite que detecta y corrige la supresión de cabeceras de Spring Security (CVE-2026-22732) identificando el uso incorrecto de la cabecera Content-Length y generando una configuración de escritura anticipada de cabeceras.

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Ver Repositorio
hace 9h 19mAún no revisado
Compartir

rewrite-cve-2026-22732

Receta de OpenRewrite que detecta código susceptible a CVE-2026-22732, un defecto de Spring Security donde establecer Content-Length a través de uno de tres métodos de respuesta omite el OnCommittedResponseWrapper de Spring Security. Debido a que el wrapper nunca ve la cabecera, onResponseCommitted() nunca se dispara, y las cabeceras de seguridad añadidas de forma diferida (X-Frame-Options, X-Content-Type-Options, Cache-Control, etc.) se descartan silenciosamente.

Qué encuentra

Los desencadenantes reales, confirmados contra Spring Security 6.4.12 vulnerable con Spring Boot 3.4.3 / Tomcat embebido:

  1. Content-Length de Servlet mediante las sobrecargas que omiten el wrapper

root@kitploit:~
response.setHeader("Content-Length", "42");
response.setIntHeader("Content-Length", 42);
response.addIntHeader("Content-Length", 42);

Estas tres sobrecargas no están sobrescritas en OnCommittedResponseWrapper. Las escrituras posteriores del cuerpo completan la longitud declarada y el contenedor confirma sin disparar el escritor de cabeceras diferido.

  • Content-Length de WebFlux mediante HttpHeaders

    root@kitploit:~
    serverHttpResponse.getHeaders().set("Content-Length", "42");
    serverHttpResponse.getHeaders().add("Content-Length", "42");
    serverHttpResponse.getHeaders().setContentLength(42L);
    
  • Confirmaciones de respuesta incondicionales de WebFlux

    root@kitploit:~
    serverHttpResponse.writeWith(Mono.just(dataBuffer));
    serverHttpResponse.writeAndFlushWith(publisher);
    serverHttpResponse.setComplete();
    
  • La receta está condicionada a la presencia de Spring Security — no emite nada en archivos que no referencian ningún tipo org.springframework.security.* — y a los rangos de versiones de Spring Security afectados. Según el aviso de Spring publicado el 2026-03-19, los rangos afectados y las versiones corregidas son:

    SerieAfectadaCorregida
    5.7.x5.7.0 – 5.7.215.7.22 (Enterprise)
    5.8.x5.8.0 – 5.8.235.8.24 (Enterprise)
    6.3.x6.3.0 – 6.3.146.3.15 (Enterprise)
    6.4.x6.4.0 – 6.4.146.4.15 (Enterprise)
    6.5.x6.5.0 – 6.5.86.5.9 (OSS)
    7.0.x7.0.0 – 7.0.37.0.4 (OSS)

    Los proyectos que resuelven una versión de Spring Security igual o superior a la corrección en su serie (o en cualquier serie futura más allá de 7.0 / 6.5) se tratan como no afectados y no reciben marcadores por sumidero ni por archivo. Los proyectos donde la versión no se puede resolver recurren a la detección habitual basada en patrones, de modo que un escáner tiende a informar de un hallazgo que no puede refutar. La tabla de datos SpringSecurityVersionByProject sigue registrando la versión resuelta y marca cada proyecto como afectado o no, para que puedas auditar lo que se filtró.

    Qué NO se marca intencionadamente

    Estos parecen peligrosos pero están rastreados por el wrapper, por lo que las cabeceras de seguridad se escriben antes de que la respuesta confirme:

    CódigoPor qué es seguro
    response.setContentLength(int) / setContentLengthLong(long)Sobrescrito — el wrapper registra la longitud declarada y dispara onResponseCommitted() cuando el cuerpo se completa.
    response.flushBuffer()Sobrescrito — llama a doOnResponseCommitted() antes de super.flushBuffer().
    response.getOutputStream().write(..) / flush() / close()Devuelve SaveContextServletOutputStream; cada write/flush/close dispara doOnResponseCommitted() antes de delegar.
    response.getWriter().write(..) / print(..) / println(..) / flush() / close()Devuelve SaveContextPrintWriter; mismo patrón.
    response.addHeader("Content-Length", v)Caso especial en el wrapper — se enruta a través de setContentLength(long).

    El endpoint /vuln/flush de la demo de Semgrep afirma que flushBuffer() es el desencadenante, pero en un Spring Security 6.4.12 vulnerable la respuesta realmente devuelve las seis cabeceras de seguridad. Los desencadenantes reales en la demo son las llamadas setIntHeader("Content-Length", ...) en /vuln/stream y /vuln/content-length.

    Detección

    Ejecuta esta:

    RecetaPropósito
    io.moderne.recipe.cve202622732.FindSpringSecurityHeaderSuppressionEjecuta todas las detecciones y emite la tabla de informe de versiones

    Bloques de construcción (avanzado)

    El agregador anterior se compone de dos recetas más pequeñas. Puedes invocarlas individualmente si solo quieres una detección.

    RecetaPropósito
    io.moderne.recipe.cve202622732.FindHttpResponseContentLengthHeaderFlujo de contaminación para el literal "Content-Length" que llega a setHeader / setIntHeader / addIntHeader (servlet) o HttpHeaders.set / add (WebFlux)
    io.moderne.recipe.cve202622732.FindHttpResponseContentLengthOrFlushBufferConfirmaciones incondicionales de WebFlux: writeWith, writeAndFlushWith, setComplete, HttpHeaders.setContentLength

    Corrección

    Ejecuta esta:

    RecetaPropósito
    io.moderne.recipe.cve202622732.FixSpringSecurityHeaderSuppressionElige la remediación más económica que cada proyecto puede aplicar realmente

    Ejecuta dos pasos en orden.

    1. Actualizar a la corrección en la propia serie del proyecto. Spring Security publicó la corrección como 6.5.9 y 7.0.4 en Maven Central. Cada actualización está condicionada a una precondición FindAffectedSpringSecuritySeries, porque UpgradeDependencyVersion solo comprueba que su objetivo es más nuevo — si se le indica ir a 7.0.4 arrastraría felizmente un proyecto 5.8 a través de dos versiones principales.

    2. Añadir una configuración de escritura de cabeceras anticipada a lo que el paso 1 no pudo corregir. Esto genera una clase @Configuration por proyecto:

    root@kitploit:~
    @Bean
    public static BeanPostProcessor eagerHeaderWriterFilterBeanPostProcessor() {
        return new BeanPostProcessor() {
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof HeaderWriterFilter) {
                    ((HeaderWriterFilter) bean).setShouldWriteHeadersEagerly(true);
                }
                return bean;
            }
        };
    }
    

    Escribir las cabeceras por adelantado hace irrelevante si el wrapper observa alguna vez la confirmación, por lo que esto cierra todos los sumideros del proyecto a la vez — incluidos aquellos a los que el análisis de contaminación no puede llegar, como el flujo Map en "Limitaciones conocidas". El BeanPostProcessor ve los filtros construidos por el DSL HttpSecurity porque AutowireBeanFactoryObjectPostProcessor los inicializa a través de la fábrica de beans. Dos correcciones publicadas de forma independiente para este CVE usan exactamente esta forma (hmcts/idam-web-public, y los forks de Spinnaker de armory-io mediante el ObjectPostProcessor equivalente).

    El paso 2 es lo que cubre los proyectos a los que el paso 1 no puede ayudar:

    SituaciónPor qué la actualización no funciona
    5.7, 5.8, 6.3, 6.4La corrección se envía solo a suscriptores de Spring Enterprise — no está en Maven Central
    6.0 - 6.2Nunca se publicó una corrección en esas series
    Versión gestionada por un BOM importadoNo se declara nada localmente para que la actualización lo edite

    Esa última fila no es un caso límite. nla/bamboo resuelve 7.0.3 — una serie con una corrección de código abierto — enteramente desde el BOM de Spring Boot, por lo que una comprobación de versión sola lo omitiría en ambos pasos y lo dejaría vulnerable. AddEagerHeaderWriterConfiguration por tanto solo difiere a la actualización cuando el proyecto tiene una corrección de código abierto disponible y declara una versión propia.

    La clase generada se coloca junto a una clase @EnableWebSecurity donde existe, recurriendo a @SpringBootApplication y luego a cualquier @Configuration, de modo que siempre aterriza en algún lugar al que el escaneo de componentes llega. Los proyectos que ya escriben cabeceras de forma anticipada, o que incluyen un OnCommittedResponseWrapper parcheado (como hace jogetworkflow/jw-community), se dejan intactos.

    Bloques de construcción (avanzado)

    RecetaPropósito
    io.moderne.recipe.cve202622732.UpgradeSpringSecurityToPatchedVersionActualización condicionada por serie a 6.5.9 / 7.0.4
    io.moderne.recipe.cve202622732.AddEagerHeaderWriterConfigurationLa configuración generada, por sí sola
    io.moderne.recipe.cve202622732.FindAffectedSpringSecuritySeriesMarca proyectos en una serie afectada; la precondición de la actualización

    Verificado contra un servidor en ejecución

    Aplicado a semgrep/cve-2026-22732-demo en Spring Security 6.4.12 vulnerable, contra Tomcat embebido. Su HeaderVerificationTest afirma que las cabeceras de seguridad están ausentes, por lo que una corrección que funcione hace que falle:

    EndpointAntesDespués
    /vuln/streamX-Content-Type-Options: nullnosniff
    /vuln/content-lengthX-Content-Type-Options: nullnosniff
    /safenosniffnosniff

    X-Frame-Options y Cache-Control siguen el mismo patrón.

    En los 16 repositorios del corpus que compilan (de 29 identificados), la corrección generó una configuración para tres y dejó correctamente intactos al resto:

    RepositorioResultado
    semgrep/cve-2026-22732-demoGenerado en com/example/vuln, junto a @EnableWebSecurity; compila, cabeceras restauradas
    nla/bambooGenerado en ui/src/bamboo, junto a @SpringBootApplication; compila. El caso 7.0.3 gestionado por BOM al que la actualización no puede llegar
    star-whale/starwhaleGenerado en ai/starwhale/mlops/configuration/security, junto a @EnableWebSecurity; compila (JDK 11, su objetivo declarado)
    hmcts/idam-web-publicDejado intacto — ya llama a setShouldWriteHeadersEagerly
    okta/okta-idx-java (6.5.9), psi-probe (6.5.11), Ant-Media-Server (6.5.11)Dejados intactos — más allá de la corrección en su serie
    apache/shenyu (6.3.1)Dejado intacto — solo reactivo; HeaderWriterFilter no tiene API de servlet detrás, y el CVE es solo de servlet
    brutusin/Brutusin-RPC (4.0.4)Dejado intacto — anterior a setShouldWriteHeadersEagerly (5.2)
    bootplus, template-app, front50, igor, rosco, spring-security, reportserverDejados intactos — no se resolvió ninguna versión de Spring Security afectada

    Re-ejecutar la corrección sobre los tres repositorios parcheados no genera nada más, por lo que la remediación es idempotente contra su propia salida en proyectos reales.

    Un segundo corpus más amplio apunta a la población que la corrección realmente aborda — cualquier aplicación servlet de Spring Security afectada, ya que no se requiere ningún sumidero. De los 64 proyectos de este tipo encontrados mediante búsqueda de código, 52 compilaron, 48 resolvieron una versión afectada, y 38 fueron parcheados; 35 de esos compilan (los otros tres fallan de forma idéntica sin el archivo generado). Los 8 proyectos en Spring Security inferior a 5.2 se omitieron correctamente. Consulta la sección 8 de SUSCEPTIBLE-REPOSITORIES.md.

    Limitaciones

    • Las detecciones de WebFlux son un peligro diferente, no este CVE. OnCommittedResponseWrapper extends jakarta.servlet.http.HttpServletResponseWrapper, por lo que CVE-2026-22732 es solo de servlet y una aplicación reactiva no está expuesta a él. Los hallazgos de FindHttpResponseContentLengthOrFlushBuffer marcan el patrón reactivo análogo y aún necesitan revisión manual, pero la corrección deliberadamente no actúa sobre ellos. AddEagerHeaderWriterConfiguration omite cualquier módulo que pueda ver HeaderWriterFilter sin la API de servlet detrás — el filtro extiende OncePerRequestFilter, y spring-security-web lleva la API de servlet como una dependencia provided no transitiva, por lo que generar allí falla con cannot access jakarta.servlet.Filter (observado en apache/shenyu).
    • Las versiones inferiores a Spring Security 5.2 se detectan pero no se corrigen. HeaderWriterFilter.setShouldWriteHeadersEagerly llega en 5.2; en 4.0.4 el filtro solo tiene un constructor y doFilterInternal. La detección sigue informando de versiones EOL, pero la remediación se retiene en lugar de emitir una llamada que no puede compilar.
    • Las cabeceras anticipadas se escriben para cada solicitud, incluidas aquellas que luego se reemplazan por un despacho de error. Ese es el compromiso que el valor predeterminado diferido de Spring Security evita, y es por lo que la actualización se ejecuta primero.

    Tablas de datos

    TablaFilas
    TaintFlowTable (de rewrite-program-analysis)Una fila por acierto de contaminación de cabecera Content-Length
    HttpResponseDirectCommitTableUna fila por acierto estructural de WebFlux
    SpringSecurityVersionByProjectUna fila por proyecto con versión de Spring Security detectada

    Ejecución

    Mediante la CLI de Moderne:

    root@kitploit:~
    mod run . --recipe io.moderne.recipe.cve202622732.FindSpringSecurityHeaderSuppression
    

    Mediante rewrite.yml:

    root@kitploit:~
    ---
    type: specs.openrewrite.org/v1beta/recipe
    name: com.example.DetectSpringSecurityHeaderSuppression
    displayName: Detect CVE-2026-22732
    recipeList:
      - io.moderne.recipe.cve202622732.FindSpringSecurityHeaderSuppression
    

    Reproducción del corpus de evaluación

    repos.csv lista los 75 repositorios públicos contra los que estas recetas se desarrollaron y midieron, fijados al commit exacto en el que cada uno se evaluó. Varios se mantienen activamente y se parchearán upstream, por lo que la columna changeset es lo que hace que los números siguientes sean reproducibles en lugar de meramente plausibles.

    root@kitploit:~
    mod git sync csv ./corpus repos.csv --with-sources
    mod build ./corpus
    mod run ./corpus --recipe=io.moderne.recipe.cve202622732.CveDevCenter
    mod devcenter ./corpus --last-recipe-run
    

    La sincronización tarda unos 20 segundos y 1,4 GB; la compilación tarda aproximadamente 15 minutos y es el único paso lento. mod devcenter escribe devcenter.html en corpus/.moderne/run/<runId>/, más uno por subdirectorio de organización.

    La columna org1 divide el corpus en grupos que reflejan por qué cada repositorio está presente — Servlet Sinks y WebFlux Sinks para las dos formas de llamada vulnerables, Patched para repositorios ya remediados upstream, Reference para Spring Security en sí y otros no consumidores, Verified para el caso comprobado contra un servidor en ejecución, Gradle para cobertura de herramientas de compilación, y Wide para la muestra masiva.

    Espera, en los commits fijados:

    Resultado
    Tarjeta de actualización39 Major, 21 Minor, 6 Patch, 4 Completed (70 repositorios)
    Tarjeta de seguridad65 repositorios expuestos
    No aplicable5 repositorios no resuelven ninguna dependencia de Spring Security

    Cuatro de esos cinco realmente no usan Spring Security — spring-projects/spring-security es la propia librería, JoeyBling/bootplus usa Apache Shiro, jenkinsci/stapler apunta directamente a la API de servlet, y infofabrik/reportserver no tiene compilación Maven ni Gradle que resolver. El quinto, xtuer/template-app, declara spring-security-web:5.0.0.RELEASE pero su compilación Gradle no resuelve ninguna dependencia durante mod build, por lo que ninguna receta puede ver la versión. Trátalo como no medido en lugar de no afectado.

    Para aplicar la corrección y comprobar el resultado:

    root@kitploit:~
    mod run ./corpus --recipe=io.moderne.recipe.cve202622732.FixSpringSecurityHeaderSuppression
    mod git apply ./corpus --last-recipe-run
    mod exec ./corpus --last-recipe-run MODERNE_BUILD_TOOL_CHECK
    

    mod git apply escribe en los checkouts en su lugar. Un check completo en todo el corpus es lento y sacará a la luz fallos no relacionados con este cambio — toolchains JDK faltantes, repositorios de dependencias inalcanzables, pruebas que ya estaban en rojo — por lo que la señal significativa es el delta contra el mismo comando ejecutado antes de aplicar.

    Qué se cubre más allá de la demo literal

    El análisis de contaminación de rewrite-program-analysis maneja el flujo de datos local y los resúmenes por método, por lo que estos patrones se detectan automáticamente:

    • Nombre de cabecera Content-Length propagado por constante. String h = "Content-Length"; response.setIntHeader(h, 42); se marca — el framework rastrea la contaminación del literal a través de la asignación local.
    • Helper que envuelve la llamada — la contaminación fluye a través de los valores de retorno mediante resúmenes de métodos.

    Limitaciones conocidas

    • Flujo a través de tipos de contenedor genéricos (Map, List, colecciones personalizadas). stash.put("k", "Content-Length") seguido de response.setIntHeader(stash.get("k"), 42) no se detecta — la identidad put/get es opaca para el análisis.

    Licencia

    Moderne Propietaria. Solo para uso de clientes de Moderne bajo los términos de un contrato comercial.

    Descargar herramienta