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
study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095 — Informe de investigación sobre las vulnerabilidades S2-045 y S2-055 de Struts2, y las vulnerabilidades CVE-2017-7525 y CVE-2017-15095 de Jackson | Kitploit
Herramientas/GitHubGitHub/secureskytechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095
Análisis de VulnerabilidadesAnálisis de CódigoExplotación de Aplicaciones WebPapers e InvestigaciónAprendizaje y EducaciónArchived
GitHubsecureskytechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095

study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095

Informe de investigación sobre las vulnerabilidades S2-045 y S2-055 de Struts2, y las vulnerabilidades CVE-2017-7525 y CVE-2017-15095 de Jackson

Ver Repositorio
106214hace 8 añosAún no revisado

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 →
Compartir

Informe de investigación sobre las vulnerabilidades S2-054, S2-055 de Struts2 y las vulnerabilidades CVE-2017-7525, CVE-2017-15095 de Jackson

Publicamos un artículo resumido que resume los puntos clave y lo hace fácil de leer. Recomendado para quienes deseen conocer primero el panorama general o no tengan tiempo suficiente.

  • SSTtechlog 08 S2-054, S2-055 y las vulnerabilidades de jackson-databind CVE-2017-7525, CVE-2017-15095 | SST SecureSky Technology Co., Ltd.
    • https://www.securesky-tech.com/column/techlog/08.html

El 1 de diciembre de 2017 se publicó una actualización de seguridad de Struts2. Antes de la publicación, corría el rumor en la lista de correo de que las vulnerabilidades de Jackson (una popular biblioteca JSON para Java) estaban relacionadas, y el autor, que también utiliza Jackson en sistemas y herramientas internas, estaba interesado en los detalles concretos.

  • https://lists.apache.org/thread.html/ed74083f2d7187e71ee5ed644c5e45ba58d0792b515d1d1cc28bfadf@%3Cdev.struts.apache.org%3E

En cuanto al contenido realmente publicado, se corrigieron los siguientes dos problemas de seguridad. La vulnerabilidad de jackson-databind, un componente de Jackson, solo afecta a S2-055.

  • S2-055 : https://cwiki.apache.org/confluence/display/WW/S2-055
    • Esta es la corrección correspondiente a CVE-2017-7525 de jackson-databind.
    • Se ha actualizado jackson-databind a la versión 2.9.2 en las dependencias de Struts. Con esto, también se cubre CVE-2017-15095, que se menciona más adelante.
  • https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.14.1
  • S2-054 : https://cwiki.apache.org/confluence/display/WW/S2-054
    • Esta es una corrección donde el plugin REST utilizaba una biblioteca JSON antigua llamada JSON-lib (http://json-lib.sourceforge.net/), pero se señaló un problema de DoS, por lo que se cambió a Jackson.
  • En el plugin REST, parece que desde antes se incluían tanto un manejador que usaba JSON-lib como uno que usaba Jackson, y el usuario podía elegir entre ellos. Se cree que el panorama completo de esta corrección es que en S2-054 se cambió el manejador predeterminado a Jackson, y además, en S2-055 se actualizó la versión anterior de Jackson a la más reciente.

    Entonces, ¿qué tipo de vulnerabilidad es CVE-2017-7525? Dado que el propio autor utiliza Jackson habitualmente para procesar JSON en Java, investigó este problema durante el fin de semana del 2 y 3 de diciembre, y ese es el contenido de este artículo.


    Entorno del autor utilizado para la verificación del código de muestra:

    • SO : Windows 10 Pro 64 bits
    • Java : Oracle JDK 1.8.0_92 64 bits
    • Groovy : 2.3.1

    Acerca de la vulnerabilidad de jackson-databind CVE-2017-7525

    En el blog de Adam Caudill se publicó una explicación de CVE-2017-7525.

    • https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/

    Resumiendo en mis propias palabras, jackson-databind proporciona la función de mapear JSON a objetos Java (clase ObjectMapper). Al llamar a ObjectMapper.enableDefaultTyping(), es posible mapear usando nombres de clases incrustados de forma arbitraria en el JSON. Creo que algunos de ustedes ya habrán tenido un mal presentimiento al saber que "se puede especificar un nombre de clase desde el JSON de entrada", y precisamente ese mal presentimiento se hizo realidad con CVE-2017-7525.

    Antes de entrar en la explicación de la vulnerabilidad, explicaré por qué se implementó dicha función en primer lugar.

    Acerca de la función ObjectMapper.enableDefaultTyping()

    Consulte el siguiente código de muestra para conocer el uso básico de la deserialización con jackson-databind. (En este artículo, se usa Groovy para los códigos de muestra de Jackson. Es conveniente poder cambiar fácilmente la versión de jackson-databind con @Grab).

    • objectmapper-demo.groovy

    En el código de muestra anterior, simplemente la clave "animal" se puede mapear directamente a la clase Animal. Entonces, ¿qué pasa en el siguiente caso?```java class Zoo { Animal animal; }

    abstract class Animal { String name; protected Animal() { } }

    class Dog extends Animal { double barkVolume; Dog() { } }

    class Cat extends Animal { boolean likesCream; int lives; Cat() { } }

    root@kitploit:~
    En esta configuración, aparecen dos casos: el contenido de la clave "animal" puede referirse a la clase Dog o a la clase Cat. Por lo tanto, se necesita información adicional para saber con qué clase realizar el mapeo.
    
    Para resolver esto, jackson-databind incorporó un procesamiento personalizado que permite incrustar el nombre de la clase de mapeo en el JSON.
    Por ejemplo, como se muestra a continuación, el contenido de la clave "animal" se convierte en un arreglo, y el primer elemento especifica el nombre de la clase.```
    {"animal":["Dog",{"name":"dog1","barkVolume":1.2}]}
    

    Esto permite que ObjectMapper.readValue() reconozca el contenido de la clave "animal" como la clase Dog y realice el mapeo. Por supuesto, de esta manera no se puede distinguir si el contenido de la clave "animal" era originalmente un array o si contenía información de nombre de clase propia de jackson-databind. Para cambiar esto se utiliza el método ObjectMapper.enableDefaultTyping(). También existe la posibilidad de definir la anotación @JsonTypeInfo en la clase. Para más detalles, consulte la documentación de Jackson a continuación:

    • JacksonPolymorphicDeserialization
      • https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

    A continuación se muestra un código de ejemplo que utiliza el método ObjectMapper.enableDefaultTyping().

    • enable-default-type-demo.groovy

    Mitigación de CVE-2017-7525 mediante la lista negra de nombres de clase

    Como hemos visto, proporcionando un nombre de clase seguido de sus propiedades en JSON, es posible, aunque con ciertas limitaciones, instanciar cualquier clase con cualquier propiedad. La vulnerabilidad CVE-2017-7525 explota esto, y el informe que probablemente la desencadenó es el siguiente:

    • Java Unmarshaller Security - Turning your data into code execution
      • https://github.com/mbechler/marshalsec

    Se ha informado sobre el peligro de que la manipulación de nombres de clase en bibliotecas de serialización/deserialización muy utilizadas en Java, como Jackson, pueda conducir a la ejecución de código arbitrario, y se han enumerado nombres de clase concretos que son peligrosos.

    No sabemos si fue en respuesta a esto, pero cronológicamente, justo después del primer commit del repositorio anterior, se creó el siguiente issue en jackson-databind y comenzó la mitigación.

    • Jackson Deserializer security vulnerability
      • https://github.com/FasterXML/jackson-databind/issues/1599

    ¿Cómo serían realmente los datos JSON y el código Java que explotan esta vulnerabilidad? El código de prueba de jackson-databind 2.8.9, que mitiga este issue, contiene pistas:

    • https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.9/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java

    Basándonos en este código de prueba, hemos preparado un código de ejemplo ajustado para poder probar su funcionamiento:

    • cve-2017-7525-check.groovy

    Al ejecutarlo especificando @Grab con la versión 2.8.9, se muestra your jackson version IS SAFE to CVE-2017-7525. Esto se debe a que en la corrección de la versión 2.8.9 se añadió una comprobación de lista negra para los nombres de clase que se instancian. Si en @Grab especificamos la versión 2.8.8 y ejecutamos, se obtiene la siguiente salida:``` your jackson version MAY NOT BE SAFE to CVE-2017-7525 com.fasterxml.jackson.databind.JsonMappingException: N/A at [Source: { "id" : 124, "obj" : [ "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl", { "transletBytecodes" : [ "AAIAZQ==" ], "transletName" : "a.b", "outputProperties" : { } } ] } ; line: 9, column: 28] (through reference chain: Bean1599["obj"]->com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl["outputProperties"]) at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:277) (...) at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:128) Caused by: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401) at java.security.AccessController.doPrivileged(Native Method) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:399) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:451) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:486) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(TemplatesImpl.java:507) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.fasterxml.jackson.databind.deser.impl.SetterlessProperty.deserializeAndSet(SetterlessProperty.java:116) ... 30 more null

    root@kitploit:~
    En el resultado de la salida, hay una línea: `at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401)`.  
    En este código de ejemplo, se lanza una NullPointerException, pero por el nombre del método se puede deducir que está ocurriendo algún procesamiento que implica efectos secundarios.  
    
    Para construir un JSON que realmente logre la ejecución de código, parece necesaria una investigación adicional.  
    Este artículo se limitará por ahora a presentar lo anterior, pero si se publican más artículos de investigación en otros sitios, me gustaría agregarlos aquí también.  
    
    Por cierto, ¿dónde está implementada la lista negra? Se encuentra en la siguiente clase:  
    * https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.9/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java#L51  
    
    En realidad, parece que en la versión 2.8.9 hubo una omisión en esta lista negra. Ese problema es CVE-2017-15095.  
    
    ### Respuesta a CVE-2017-15095 que mejoró la lista negra  
    
    En cuanto a la mejora de la omisión de la lista negra, primero se añadió `s.add("com.sun.rowset.JdbcRowSetImpl");` en https://github.com/FasterXML/jackson-databind/issues/1680.  
    Después de que se lanzara la versión 2.9.0 con ese cambio, posteriormente se agregó la siguiente comprobación de la lista negra en https://github.com/FasterXML/jackson-databind/issues/1737.```java
    // [databind#1737]; JDK provided
    s.add("java.util.logging.FileHandler");
    s.add("java.rmi.server.UnicastRemoteObject");
    // [databind#1737]; 3rd party
    s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor");
    s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
    s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
    s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");
    

    Ahora se han lanzado las versiones 2.8.10 / 2.9.1, con lo que se completa la respuesta a CVE-2017-15095.

    Código de prueba para comprobar el funcionamiento de la lista negra en 2.8.10:

    • https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.10/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java#L57

    A continuación se muestra un código de muestra ajustado para verificar el funcionamiento basado en este código de prueba.

    • cve-2017-15095-check.groovy

    Al ejecutar la versión 2.8.10, que se dice que tiene la respuesta completa, especificándola con @Grab, se muestra your jackson version IS SAFE to CVE-2017-15095. A continuación, al ejecutar la versión 2.8.9 anterior a la mejora de la lista negra especificándola con @Grab, se genera lo siguiente:``` your jackson version MAY NOT BE SAFE to CVE-2017-15095 com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.logging.FileHandler, problem: \tmp\foobar.txt.lck at [Source: { "v" : [ "java.util.logging.FileHandler", "/tmp/foobar.txt" ] } ; line: 5, column: 5] (through reference chain: PolyWrapper["v"]) at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:277) (...) Caused by: java.nio.file.NoSuchFileException: \tmp\foobar.txt.lck (...) at java.util.logging.FileHandler.openFiles(FileHandler.java:459) at java.util.logging.FileHandler.(FileHandler.java:292) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call1(AnnotatedConstructor.java:129) at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:318) ... 31 more null

    root@kitploit:~
    En la versión anterior a la corrección, se observa que el nombre de clase `java.util.logging.FileHandler` elude la verificación de la lista negra y, al ser instanciado, intenta abrir un archivo.
    En la versión posterior a la corrección, es atrapado por la verificación de la lista negra y se lanza una excepción `JsonMappingException`.
    
    La lista negra a partir de la versión 2.8.10 es la siguiente. La parte que comienza con el comentario `[databind#1737]` es la lista negra adicional correspondiente a CVE-2017-15095.
    * https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.10/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java#L52
    
    ### Condiciones afectadas por la vulnerabilidad, grado de explotación del ataque y medidas del lado de la aplicación
    
    Resumiendo los resultados anteriores, las condiciones necesarias para verse afectado por la vulnerabilidad de jackson-databind son las siguientes:
    1. Usando jackson-databind 2.8.9 / 2.9.0 o inferior
    2. Procesando JSON obtenido de una fuente no confiable de una de las siguientes maneras:
       * Llamar a `ObjectMapper.enableDefaultTyping()` antes de deserializar.
       * No se llama a `ObjectMapper.enableDefaultTyping()`, pero se utiliza la anotación `@JsonTypeInfo` en la declaración de clase para permitir el mapeo y se deserializa.
       * Incluso si no se usa en el código de la aplicación, el framework puede deserializar automáticamente según el encabezado de solicitud `Accept` o la extensión de la URL.
    3. Contener en el classpath clases que podrían ser explotadas mediante vulnerabilidades de serialización/deserialización de Java ("Gadget").
    4. Usar tipos como `Object` en los campos miembro de la clase Java de destino que puedan aceptar clases Gadget.
       * Si se usan tipos como clases Bean específicas de la aplicación que sean incompatibles con las clases utilizadas en los Gadget, es posible rechazar la instanciación con un error de verificación de tipo antes de crear la instancia (excepto si la propia clase Bean específica de la aplicación contiene vulnerabilidades de deserialización).
    
    En cuanto a si realmente se ve afectado, parece depender en gran medida del código del lado de la aplicación, como la forma de usar/configurar `ObjectMapper`, la combinación de la anotación `@JsonTypeInfo`, los campos miembro de la clase destino, etc.
    
    Además, si los nombres de clave en el JSON no existen en la clase Java de destino, Jackson simplemente los ignora. Por lo tanto, para que un ataque tenga éxito, es necesario personalizarlo según el JSON de cada aplicación, y parece muy difícil crear código de ataque que pueda reutilizarse en múltiples aplicaciones.
    
    Además, con respecto a la condición 4, en la práctica común, no se suele declarar un campo de clase Java como tipo `Object`. Las clases que permiten la ejecución de código arbitrario son, en su mayoría, incompatibles con las clases Bean creadas en la aplicación.
    
    Por lo tanto, parece baja la posibilidad de que ocurran ataques a gran escala o que realmente se explote esta vulnerabilidad para causar daños (es decir, que el ataque tenga éxito).
    
    En cuanto a las medidas del lado de la aplicación, para la condición 3, dado que también se pueden explotar clases incluidas en el JDK, parece que prácticamente no se puede mitigar. Por lo tanto, la medida básica es actualizar jackson-databind a la última versión. Si no se puede actualizar a la última versión, será necesario eliminar la llamada a `ObjectMapper.enableDefaultTyping()` o la anotación `@JsonTypeInfo` y rediseñar para no depender de ellas. Por ejemplo, se podría crear un serializador personalizado.
    
    Sin embargo, si ya se está utilizando como una API invocable de forma remota, no se puede cambiar el formato JSON tan fácilmente. En cuanto a la anotación `@JsonTypeInfo`, parece que, según la configuración, se pueden limitar las subclases o aceptar solo los nombres de clase previstos por el programador. Consulte los siguientes documentos para más detalles.
    * JacksonPolymorphicDeserialization
      * https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
    
    #### Sobre los pros y contras de la mitigación mediante lista negra y la creación de un deserializador personalizado
    
    jackson-databind 2.8.10 / 2.9.1 abordó CVE-2017-7525 y CVE-2017-15095 mediante una lista negra. Sin embargo, como es evidente en los problemas relacionados con OGNL en Struts2, la mitigación mediante lista negra no es perfecta. (Personalmente, creo que es una medida efectiva hasta cierto punto para el nivel de los llamados 'script kiddies' que solo usan herramientas de escaneo).
    
    Por lo tanto, si se desea una mitigación realmente fundamental, el autor considera que es importante deshabilitar o no usar funciones como `ObjectMapper.enableDefaultTyping()` que incrustan información de clase en el JSON. Entonces, ¿cómo se puede resolver el problema que `ObjectMapper.enableDefaultTyping()` pretendía resolver?
    
    El autor tampoco tiene una solución alternativa que pueda considerarse correcta. La raíz del problema es 'poder mapear clases Java ambiguas sin depender de JSON no confiable'. Como enfoque para hacerlo posible, el autor piensa que podría ser crear un deserializador personalizado. Un deserializador personalizado permite recibir JSON durante la deserialización y controlar el objeto generado desde el código del programa.
    
    Por ejemplo, si llega `{"animal":{"name":"dog1","barkVolume":1.2}}`, se puede determinar que 'como hay una clave `barkVolume`, se instancia como clase Dog'; o si llega `{"animal":{"name":"cat1","likesCream":true,"lives":10}}`, se puede determinar que 'como hay claves `likesCream` y `lives`, se instancia como clase Cat'. Usando esto, no es necesario incrustar el nombre de clase en el JSON.
    
    Personalmente, tengo la impresión de que el formato JSON con nombres de clase incrustados dificulta la interoperabilidad con otros lenguajes/bibliotecas (si conoce alguna otra extensión similar en otros lenguajes/bibliotecas, por favor hágamelo saber). Si se asume la interoperabilidad con otros sistemas, parece más razonable crear un deserializador personalizado en Jackson que forzar a los demás a incrustar nombres de clase según las necesidades de Jackson.
    
    Creo que hay otras soluciones, por lo que agradecería que los lectores compartieran sus opiniones si tienen alguna otra solución. (Un ejemplo extremo sería no mapear a clases individuales, sino deserializar todo en formato `Map<String, Object>` o `List<String, Object>`).
    
    He encontrado algunos artículos de referencia para crear deserializadores personalizados; aunque están en inglés, dejo los enlaces.
    * Jackson: create a custom JSON deserializer with StdDeserializer and JsonToken classes | Dede Blog
      * http://www.davismol.net/2015/05/20/jackson-create-a-custom-json-deserializer-with-stddeserializer-and-jsontoken-classes/
    * Getting Started with Deserialization in Jackson | Baeldung
      * http://www.baeldung.com/jackson-deserialization
    * Custom JSON Deserialization with Jackson - DZone Integration
      * https://dzone.com/articles/custom-json-deserialization-with-jackson
    * Building a Custom Jackson Deserializer - The Boy Wonders
      * http://www.robinhowlett.com/blog/2015/01/01/building-a-custom-jackson-deserializer/
    
    JavaDoc de jackson-databind (versiones 2.8, 2.9):
    * https://fasterxml.github.io/jackson-databind/javadoc/2.8/
    * https://fasterxml.github.io/jackson-databind/javadoc/2.9/
    
    El autor también ha creado un código de ejemplo de deserializador personalizado; espero que sirva como sugerencia.
    * [custom-deserializer-demo.groovy](https://github.com/SecureSkyTechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095/blob/master/custom-deserializer-demo.groovy)
    
    ## Acerca de S2-055
    
    Hasta ahora hemos visto las vulnerabilidades de Jackson. Ahora, ¿cómo afectan realmente al plugin REST de Struts2? Lo hemos verificado usando struts2-rest-showcase incluido en Struts2.
    
    El uso del plugin REST de Struts se basó en lo siguiente:
    * http://struts.apache.org/plugins/rest/
    
    ### El plugin REST de Struts2 no llama a ObjectMapper.enableDefaultTyping()
    
    Por cierto, las condiciones para ser vulnerable en CVE-2017-7525 eran las siguientes:
    * Procesando JSON obtenido de una fuente no confiable de una de las siguientes maneras:
      * Llamar a `ObjectMapper.enableDefaultTyping()` antes de deserializar.
      * No se llama a `ObjectMapper.enableDefaultTyping()`, pero se utiliza la anotación `@JsonTypeInfo` en la declaración de clase para permitir el mapeo y se deserializa.
    
    Al verificar si el plugin REST de Struts2 contiene código que cumpla estas condiciones, se confirmó que no incluye ninguna. De hecho, en la versión 2.5.14 anterior a la corrección, ni `ObjectMapper.enableDefaultTyping()` ni `@JsonTypeInfo` se usaban en el plugin REST ni en todo el árbol de fuentes de Struts2 tras una búsqueda con grep.
    * https://github.com/apache/struts/tree/STRUTS_2_5_14
    
    En todo el árbol de fuentes de Struts2, la única clase que usa ObjectMapper de Jackson es org.apache.struts2.rest.handler.JacksonLibHandler. Al verificar el código fuente, ciertamente no se utiliza `ObjectMapper.enableDefaultTyping()` en la versión 2.5.14.
    * https://github.com/apache/struts/blob/STRUTS_2_5_14/plugins/rest/src/main/java/org/apache/struts2/rest/handler/JacksonLibHandler.java
      * Este archivo Java no ha cambiado en 2.5.14.1.
    
    Por lo tanto, se considera que el plugin REST en sí no tenía problemas con CVE-2017-7525 incluso en la versión 2.5.14. La vulnerabilidad ocurre cuando la aplicación establece `@JsonTypeInfo` en los campos de las clases que mapean el JSON. Por lo tanto, en la verificación con struts2-rest-showcase a continuación, se ha configurado `@JsonTypeInfo` en los campos de destino agregados en el lado de la aplicación.
    
    Por cierto, en Struts2 también hay un plugin JSON.
    * http://struts.apache.org/plugins/json/
    * Al revisar el código fuente del plugin JSON, en su pom.xml no incluye otras bibliotecas JSON como dependencias.
    * Parece que implementa su propio procesamiento JSON.
    * https://github.com/apache/struts/tree/STRUTS_2_5_14/plugins/json
    * Por lo tanto, se cree que la vulnerabilidad de jackson-databind no afecta al plugin JSON.
    
    ### Hacer que struts2-rest-showcase sea compatible con Jackson
    
    struts2-rest-showcase es un ejemplo que implementa CRUD de la clase Order usando el plugin REST. Aquí agregaremos las clases Zoo, Animal, Cat, Dog utilizadas en el código de ejemplo de vulnerabilidad de Jackson, y un ZooController para procesar su CRUD en JSON.
    
    Consulte el código fuente completo a continuación. (Este artículo ha verificado la compilación y ejecución con JDK8)
    * [rest-showcase](https://github.com/SecureSkyTechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095/tree/master/rest-showcase)
    
    Principales modificaciones:
    * Se cambió el puerto de escucha del plugin jetty-maven-plugin a 18088. (`mvn jetty:run`)
    * Se agregaron jackson-core y jackson-databind como dependencias.
    * Se agregaron las clases Zoo, Animal(abstract), Dog, Cat. Se agregó la clase ZooService como capa de servicio.
    * Se agregó un ZooController con CRUD mínimo. (Se omitió la vista JSP)
    * En struts.xml se cambió el manejador JSON a JacksonLibHandler.
    * Se incorporó maven-wrapper para que, si solo se tiene JDK, se pueda compilar y ejecutar directamente con mvnw / mvnw.bat.
    
    Compilación y ejecución:
    1. Después de clonar el repositorio, vaya al directorio rest-showcase y ejecute `mvnw jetty:run`. (Tenga en cuenta que la primera ejecución descargará Maven, lo que puede demorar unos minutos o incluso más de 10 minutos dependiendo del caso).
    1. Acceda a http://localhost:18088/struts2-rest-showcase/; si se muestra la lista de Orders, es exitoso.
    1. Para finalizar la ejecución, puede usar Ctrl-C.
    1. Si modifica archivos Java, finalice con Ctrl-C y ejecute nuevamente `mvnw jetty:run`.
    
    Verificación de funcionamiento con comando curl: (asumiendo que se pasa a través del proxy local http localhost:8080)```
    一覧取得:
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo"
    
    ID指定:
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo/1"
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo/2"
    
    削除:
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo/2" -X DELETE
    

    En el Zoo.java del repositorio, el campo animal es como se muestra a continuación, donde @JsonTypeInfo está comentado y es del tipo Animal, una clase abstracta.```java //@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_ARRAY) public Animal animal; //public Object animal;

    root@kitploit:~
    Aquí, enviaremos una solicitud JSON mediante el método POST y llamaremos al método ZooController.create().```
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo" -X POST -H "Content-Type: application/json" -d '{"id":"3","animal":{"name":"dog2","barkVolume":2.3}}'
    

    Entonces ocurrió una excepción que incluía el siguiente mensaje de error. Debido a que la clase Animal es abstracta, no se pudo crear una instancia.``` Can not construct instance of org.demo.rest.example.Animal: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

    root@kitploit:~
    Por lo tanto, descomenta y habilita el `@JsonTypeInfo` del campo `animal`. Detén la aplicación web con Ctrl-C y vuelve a ejecutar `mvnw jetty:run`.```java
    // 次のimportを忘れずに追加
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    //...
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_ARRAY)
        public Animal animal;
        //public Object animal;
    

    Ahora se puede incrustar el nombre de la clase en el JSON. Probemos a hacer un POST del JSON con el nombre de la clase incrustado usando el siguiente comando curl.``` curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo" -X POST -H "Content-Type: application/json" -d '{"id":"3","animal":["org.demo.rest.example.Dog",{"name":"dog2","barkVolume":2.3}]}'

    root@kitploit:~
    → `HTTP/1.1 201 Created` が返されます。一覧取得をしてみると、たしかに追加されたことを確認できます。
    
    ### Struts2 REST plugin 2.5.14 で CVE-2017-7525 を確認
    
    リポジトリの pom.xml では `<parent>` の struts のartifactで、バージョンを 2.5.14 を指定しているため、そのままではCVE-2017-7525に脆弱です。
    それを確認するため、以下のcurlコマンドを実行してみます。クラス名とその中身は cve-2017-7525-check.groovy を参考にしていますので、jackson-databind 2.8.8 の時と同じ反応が返されれば、脆弱であると考えられます。```
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo" -X POST -H "Content-Type: application/json" -d '{"id":"3","animal":["com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",{"transletBytecodes":["AAIAZQ=="],"transletName":"a.b","outputProperties":{}}]}'
    

    → 以下のレラーメッセージを含む例外がthrowされました。``` java.lang.IllegalArgumentException: Class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl not subtype of [simple type, class org.demo.rest.example.Animal]

    root@kitploit:~
    Parece que se produjo una `IllegalArgumentException` porque el tipo del campo `animal` es la clase `Animal`, que no es un subtipo de la clase `com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl`.
    
    Ahora, modifiquemos el campo `animal` de `Zoo.java` al tipo `Object` y ejecutemos `mvnw jetty:run` de nuevo.```java
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_ARRAY)
        //public Animal animal;
        public Object animal;
    

    Con esto, al ejecutar el comando curl anterior nuevamente, se produjo una excepción que incluye el siguiente seguimiento de pila.``` Caused by: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401) ~[?:1.8.0_92]

    root@kitploit:~
    Esta es la misma excepción de caso vulnerable que se verificó con cve-2017-7525-check.groovy.
    
    Por lo anterior, se confirmó la existencia de la vulnerabilidad CVE-2017-7525 de jackson-databind en el plugin Struts2 REST 2.5.14.
    
    Además, se supo que es necesario usar el tipo Object además de `@JsonTypeInfo`.
    
    Lo siguiente es una opinión personal del autor, pero no parece común especificar deliberadamente una clase que sea compatible con la clase Object o clases que puedan usarse como Gadget en vulnerabilidades de deserialización de Java como tipo de campo en clases de datos al crear una API REST. Por lo tanto, siento que puede ser difícil tener éxito en un ataque real.
    
    ### Confirmación de la corrección en Struts2 REST plugin 2.5.14.1
    
    Entonces, verifiquemos si la vulnerabilidad fue corregida en la versión 2.5.14.1.
    
    Modifique la versión del artifact `<parent>` en pom.xml a 2.5.14.1, reinicie con `mvnw jetty:run` y ejecute el mismo comando curl de antes.```
    curl -v -x localhost:8080 -H "Accept: application/json" "http://localhost:18088/struts2-rest-showcase/zoo" -X POST -H "Content-Type: application/json" -d '{"id":"3","animal":["com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",{"transletBytecodes":["AAIAZQ=="],"transletName":"a.b","outputProperties":{}}]}'
    

    → Se produjo una excepción que incluye el siguiente mensaje de error.``` com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid type definition for type com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl: Illegal type (com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl) to deserialize: prevented for security reasons

    root@kitploit:~
    これは cve-2017-7525-check.groovy で検証した時と同じ、脆弱性が修正された後の例外です。
    
    Eclipse等のMavenに対応したIDEで開いて、依存性を解決した後のjackson-databindのバージョンを見てみると、たしかに 2.9.2 になっていることが確認できると思います。IDEがない場合は、 `mvnw help:effective-pom` で最終的なpomを出力できますので、そこで jackson-databind を検索すれば version 2.9.2 を使用していることを確認できると思います。
    
    CVE-2017-15095 については省略しますが、以上より 2.5.14.1 で jackson-databind の脆弱性に対応できたことを確認できました。
    
    ### PoC de S2-055
    
    ※ Añadido el 2017-12-08
    
    Se han publicado un artículo de investigación y un informe PoC sobre S2-055.
    * S2-055漏洞环境搭建与分析 | 绿盟科技博客
      * http://blog.nsfocus.net/s2-055/
    
    Si lo leemos con la ayuda de Google Translate, parece que [los autores] tienen la misma opinión sobre las condiciones de explotación y la viabilidad del ataque.
    
    De hecho, se ha modificado rest-showcase y se muestra un PoC de comunicación HTTP donde se inició una calculadora.
    
    Tomando solo la parte JSON, probé primero con Jackson solo, y el siguiente es el código de muestra.
    * [cve-2017-7525-poc.groovy](https://github.com/SecureSkyTechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095/blob/master/cve-2017-7525-poc.groovy)
    
    Cuando se ejecuta especificando la versión 2.8.8 aquí, en el entorno del autor se obtuvo la siguiente salida.```
    your jackson version MAY NOT BE SAFE to CVE-2017-7525
    (...)
    Caused by: java.lang.NullPointerException
            at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401)
    (...)
    

    cve-2017-7525-check.groovy の時と同様、run()メソッドが走ってNullPointerExceptionが発生しました。ただ、電卓は起動しませんでした。

    Al igual que con cve-2017-7525-check.groovy, se ejecutó el método run() y se produjo una NullPointerException. Sin embargo, la calculadora no se inició.

    推測になりますが、xalanのTemplatesImplはJavaの中に入ってるクラスなので、Java側で何かしら修正をしている可能性が考えられます。 あるいは、実際の攻撃成功にはもっとナイーブな条件が必要なのかもしれません。

    Es una conjetura, pero como TemplatesImpl de xalan es una clase dentro de Java, es posible que Java haya hecho alguna modificación. O quizás se necesiten condiciones más ingenuas para que el ataque tenga éxito.

    PoC記事の方では検証に使ったJavaのバージョンまでは示されておらず、電卓を動かすところまで辿り着けませんでした。 追加情報が出たら、また検証してみたいと思います。

    El artículo de PoC no mostraba la versión de Java utilizada en la verificación, y no se pudo llegar a ejecutar la calculadora. Si aparece información adicional, me gustaría volver a verificarlo.

    S2-054 について

    Acerca de S2-054

    ここまで S2-055 を発端として主にJacksonの脆弱性 CVE-2017-7525, CVE-2017-15095 について紹介してきました。 では、もう一方の S2-054 についてはどういう状況か、ざっくりと調べた結果をまとめます。

    Hasta ahora, hemos presentado principalmente las vulnerabilidades de Jackson CVE-2017-7525 y CVE-2017-15095 a partir de S2-055. Ahora, resumiré los resultados de una investigación aproximada sobre la situación de la otra, S2-054.

    結論から言うと、本記事執筆時点(2017-12-03) では具体的な情報は見つけられませんでした。脆弱性有無を検査できるPoCなども見つけられていません。

    En conclusión, al momento de escribir este artículo (2017-12-03), no se encontró información concreta. Tampoco se encontraron PoC que permitan verificar la existencia de la vulnerabilidad.

    S2-054 の情報公開ページでは REST plugin では古いJSON-libライブラリが使われており、改ざんされたJSONによりDoSアタックが可能と説明されています。

    En la página de divulgación de S2-054, se explica que el plugin REST utiliza una biblioteca JSON-lib antigua y que un JSON manipulado puede permitir un ataque DoS.

    • https://cwiki.apache.org/confluence/display/WW/S2-054

    The REST Plugin is using an outdated JSON-lib library which is vulnerable and allow perform a DoS attack using malicious request with specially crafted JSON payload.

    この問題の対応としてリリースされた 2.5.14.1 のページでは、これに対応するJIRAのチケットとしてWW-4892がリンクされています。

    En la página de la versión 2.5.14.1 lanzada como solución a este problema, se enlaza el ticket de JIRA WW-4892.

    • https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.14.1

    WW-4892 を確認してみたのですが、どこにもDoSやJSON-libの脆弱性について言及がありません。"Description"を読んでも、単にJSON-libが古くてメンテされてないので、デフォルトhandlerをJacksonに変更する、としか書かれてないように読めます。

    Revisé WW-4892, pero no hay mención alguna de DoS o vulnerabilidades de JSON-lib. Incluso al leer la 'Descripción', solo dice que JSON-lib es antiguo y no se mantiene, por lo que se cambia el manejador predeterminado a Jackson.

    • https://issues.apache.org/jira/browse/WW-4892

    GitHub側のpullreqは以下のようですが、こちらでも具体的なJSON-libの問題への言及がありません。

    El pullreq del lado de GitHub es el siguiente, pero tampoco hay mención de problemas específicos de JSON-lib.

    • https://github.com/apache/struts/pull/187

    そこで、JSON-lib側を見てみることにしました。公式サイトは以下になります。

    Por lo tanto, decidí echar un vistazo al lado de JSON-lib. El sitio oficial es el siguiente.

    • http://json-lib.sourceforge.net/

    また2017年現在は、GitHubで管理されているようです。

    Además, a partir de 2017, parece que se gestiona en GitHub.

    • https://github.com/aalmiray/Json-lib

    どちらが最新でしょうか?本記事執筆時点ではGitHub側でのリリースはありません。そこでMaven Centralリポジトリの登録状況を見てみます。

    ¿Cuál es el más reciente? Al momento de escribir este artículo, no hay lanzamientos en GitHub. Entonces, veamos el estado de registro en el repositorio de Maven Central.

    "json-lib" で検索すると、いくつかgroupIdがヒットします。

    Al buscar 'json-lib', aparecen varios groupId.

    • http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22json-lib%22

    どのgroupIdが正解か、実際に Struts2 2.5.14.1 の REST plugin のpom.xmlを確認します。

    Para saber qué groupId es correcto, revisamos el pom.xml del plugin REST de Struts2 2.5.14.1.

    • https://github.com/apache/struts/blob/STRUTS_2_5_14_1/plugins/rest/pom.xml

    • → groupId = net.sf.json-lib, artifactId = json-lib でした。

    • → groupId = net.sf.json-lib, artifactId = json-lib.

    groupId = net.sf.json-lib, artifactId = json-lib のリリースバージョンを見てみると、2010年12月のバージョン 2.4 が最後のリリースです。

    Al observar las versiones de lanzamiento de groupId = net.sf.json-lib, artifactId = json-lib, la última versión es la 2.4 de diciembre de 2010.

    • http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22net.sf.json-lib%22%20AND%20a%3A%22json-lib%22

    sourceforge側のページを確認してみると、やはりこちらも2012年12月のバージョン2.4が最後のリリースです。

    Al revisar la página de sourceforge, también aquí la última versión es la 2.4 de diciembre de 2012.

    • https://sourceforge.net/projects/json-lib/files/json-lib/

    実際、GitHub側にはリリースタグこそ打たれていませんが、commitログをたどると 2010年12月にバージョン2.4のリリースというcommitがあります。 また、それ以降はpullreqマージは動いていますが、リリースの動きはありませんでした。

    De hecho, en el lado de GitHub no hay etiquetas de lanzamiento, pero si se sigue el registro de commits, hay un commit de lanzamiento de la versión 2.4 en diciembre de 2010. Además, desde entonces se han fusionado pull requests, pero no ha habido actividad de lanzamiento.

    GitHub側のIssueをclosed含め見てみると、DoSにつながるようなタイトルは見当たりません。

    Al revisar los Issues de GitHub, incluidos los cerrados, no se encuentran títulos que puedan conducir a DoS.

    • https://github.com/aalmiray/Json-lib/issues?utf8=%E2%9C%93&q=is%3Aissue

    sourceforge側のチケットを見てみると、ようやく memory leak 問題のチケットに突き当たりました。いずれもまだ修正されていない模様です。

    Al revisar los tickets de sourceforge, finalmente nos topamos con tickets sobre el problema de memory leak. Parece que ninguno ha sido corregido aún.

    • Json-lib / Bugs / #124 memory leak in 2.2.2, not fixed correctly in 2.4

      • https://sourceforge.net/p/json-lib/bugs/124/
    • Json-lib / Bugs / #118 Possible memory leak in Tomcat

      • https://sourceforge.net/p/json-lib/bugs/118/
    • → 2.2 までで ThreadLocal を使ったことによるmemory leak問題があって、2.4でSoftReferenceを使って対応しているが、根本的な対応になってないよ、というチケット内容と読み取れました。

    • → Se interpretó que había un problema de memory leak debido al uso de ThreadLocal hasta la versión 2.2, y que en la versión 2.4 se abordó con SoftReference, pero no es una solución fundamental.

    ようやくmemory leak問題が残っているらしい、というところまでは辿り着けたのですが、筆者の力量と時間の都合で、この先の調査まではできませんでした。 もし実際にこのパターンのJSONでmemory leakが発生した、あるいはDoSになった、という具体的な情報があれば、ご教示いただけると大変助かります。

    Finalmente llegamos a la conclusión de que el problema de memory leak parece persistir, pero debido a la capacidad y tiempo del autor, no se pudo investigar más allá. Si hay información concreta de que realmente ocurrió un memory leak con este patrón de JSON, o que resultó en un DoS, agradecería mucho que me lo hicieran saber.

    参考 : Spring Securityの対応例(2017年6月)

    Referencia: Ejemplo de respuesta de Spring Security (junio de 2017)

    Jacksonを使っているOSSは沢山あるため、この脆弱性に影響を受けた他のライブラリ・フレームワークも存在します。 例としてPivotal製品群の Spring Security が影響を受けており、2017年6月に情報公開されています。

    Debido a que hay muchos OSS que usan Jackson, existen otras bibliotecas y frameworks afectados por esta vulnerabilidad. Como ejemplo, Spring Security de la familia de productos Pivotal se vio afectado, y se publicó información en junio de 2017.

    • CVE-2017-4995: Jackson Configuration Allows Code Execution with Unknown “Serialization Gadgets” | Security | Pivotal
      • https://pivotal.io/security/cve-2017-4995

    それ以外の、例えば Spring Framework 本体はどうかというと、少なくとも https://pivotal.io/security/ の方にはJackson由来のアップデート情報は公開されておりません。

    En cuanto a otros, por ejemplo, el propio Spring Framework, al menos en https://pivotal.io/security/ no se ha publicado información de actualización derivada de Jackson.

    だからといって安心することはできません。もともと Spring Framework でのJacksonはかなりカスタマイズが容易な設計になっており、アプリケーション固有の ObjectMapper を生成することも可能です。Jacksonの設定/機能をアプリケーション側でカスタマイズしていないか? @JsonTypeInfo を使っていないか?など念のため確認したほうが良いでしょう。

    Sin embargo, no podemos estar tranquilos por eso. Originalmente, Jackson en Spring Framework está diseñado para ser bastante personalizable, y es posible generar ObjectMapper específico de la aplicación. Es mejor verificar por si acaso si se han personalizado configuraciones/funcionalidades de Jackson en el lado de la aplicación, o si se está usando @JsonTypeInfo.

    CVE-2017-7525, CVE-2017-15095 の簡単な時系列整理

    Resumen cronológico simple de CVE-2017-7525 y CVE-2017-15095

    jackson-databind のGitHub Issue/リリース情報や、RedHat のbugzilla などの参考リンクを時系列順に整理してみました。 間違っていたら遠慮なく筆者までご指摘・ご連絡ください。

    He organizado cronológicamente las referencias, como los Issues de GitHub de jackson-databind, información de lanzamientos, y bugzilla de RedHat. Si hay errores, no dude en señalármelos o contactarme.

    2017-04

    2017-04

    • https://github.com/FasterXML/jackson-databind/issues/1599 にて初期の改修が進む。バージョン管理の都合で、hot-fix扱いで以下のバージョンがリリースされる。
      • 2.7.9.1 : 2.7.9 に対するhot-fix
      • 2.8.8.1 : 2.8.8 に対するhot-fix
      • 他、2.9.0.pr3 もリリースされている。

    Las primeras correcciones avanzaron en https://github.com/FasterXML/jackson-databind/issues/1599. Por razones de gestión de versiones, se lanzaron las siguientes versiones como hot-fix:

    • 2.7.9.1: hot-fix para 2.7.9
    • 2.8.8.1: hot-fix para 2.8.8
    • Además, se lanzó 2.9.0.pr3.

    2017-06

    2017-06

    • その他の改修も含めた 2.8.9 がリリースされる。

    • 次のbugzillaでRedHat製品での対応が進む。

      • https://bugzilla.redhat.com/show_bug.cgi?id=1462702
    • Se lanzó 2.8.9 que incluye otras correcciones.

    • En el siguiente bugzilla, avanzó el soporte para productos RedHat.

      • https://bugzilla.redhat.com/show_bug.cgi?id=1462702

    2017-07

    2017-07

    • 既にサポートが終わっていた 2.6系 の2.6.7に対して、この問題についてのhot-fixとして 2.6.7.1 がリリースされる。

    • RedHatからCVE-2017-7525の情報が公開される。

      • https://access.redhat.com/security/cve/CVE-2017-7525
    • Para 2.6.7 de la serie 2.6, que ya no tenía soporte, se lanzó 2.6.7.1 como hot-fix para este problema.

    • RedHat publicó información sobre CVE-2017-7525.

      • https://access.redhat.com/security/cve/CVE-2017-7525

    この時点でのblack-listの一覧は以下になっていた。

    La lista negra en ese momento era la siguiente:```java s.add("org.apache.commons.collections.functors.InvokerTransformer"); s.add("org.apache.commons.collections.functors.InstantiateTransformer"); s.add("org.apache.commons.collections4.functors.InvokerTransformer"); s.add("org.apache.commons.collections4.functors.InstantiateTransformer"); s.add("org.codehaus.groovy.runtime.ConvertedClosure"); s.add("org.codehaus.groovy.runtime.MethodClosure"); s.add("org.springframework.beans.factory.ObjectFactory"); s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); s.add("org.apache.xalan.xsltc.trax.TemplatesImpl");

    root@kitploit:~
    Aquí, durante el mismo mes, se lanzó la versión 2.9.0 como una corrección adicional para contrarrestar la black-list.
    * https://github.com/FasterXML/jackson-databind/issues/1680
    
    Esto fue añadido:```java
    s.add("com.sun.rowset.JdbcRowSetImpl");
    

    Además, durante el mismo mes, se abre el siguiente Issue:

    • https://github.com/FasterXML/jackson-databind/issues/1737

    → Se agrega lo siguiente a la lista negra, y esto se incorpora en 2.8.10 / 2.9.1.```java // [databind#1737]; JDK provided s.add("java.util.logging.FileHandler"); s.add("java.rmi.server.UnicastRemoteObject"); // [databind#1737]; 3rd party s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor"); s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean"); s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource"); s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");

    root@kitploit:~
    ### 2017-08
    
    * Se lanza la versión 2.8.10, que aborda los issues #1680, #1737.
    * Además, en agosto se abren los siguientes issues, y se discute de manera integral la respuesta como CVE-2017-7525.
      * https://github.com/FasterXML/jackson-databind/issues/1723
    * En el blog de Adam Caudill se publica una explicación del exploit de CVE-2017-7525.
      * https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/
    
    ### 2017-09
    
    * Se lanza la versión 2.9.1, que aborda el issue #1737.
    
    ### 2017-10
    
    En el siguiente bugzilla, se inicia el trabajo para aplicar la lista negra de las versiones 2.8.10 / 2.9.1, ya que la corrección de CVE-2017-7525 en las versiones 2.8.9 / 2.9.0 era insuficiente, y se identifica como CVE-2017-15095.
    * https://bugzilla.redhat.com/show_bug.cgi?id=1506612
    
    ### 2017-11
    
    * RedHat publica información sobre CVE-2017-15095.
      * https://access.redhat.com/security/cve/cve-2017-15095
    
    * En el issue de jackson-databind también se intercambian preguntas y respuestas sobre el estado de la respuesta a CVE-2017-15095.
      * https://github.com/FasterXML/jackson-databind/issues/1847
      * Se responde que ya está cubierto en las versiones 2.8.10 / 2.9.1.
    
    ### 2017-12
    
    * Se publica un artículo explicativo en el blog de desarrolladores de Scutum, un WAF en la nube.
      * https://www.scutum.jp/information/waf_tech_blog/2017/12/waf-blog-052.html
      * En este artículo se menciona que, en la lista negra de la versión 2.9.3, hay una deficiencia en la clase de Spring que, aunque no representa un problema urgente, podría dar lugar a una nueva actualización.
      * También se debate si la responsabilidad de esta vulnerabilidad recae realmente en la biblioteca o más bien en la aplicación.
    
    ## Sobre las tendencias futuras de vulnerabilidades relacionadas con la serialización/deserialización en Java
    
    Desde hace un par de años, tengo la impresión de que han aumentado los informes de vulnerabilidades relacionadas con la serialización/deserialización en Java.
    Por ejemplo, la información sobre vulnerabilidades de productos Pivotal, incluido Spring, se publica en https://pivotal.io/security/. De hecho, en 2017, además de CVE-2017-4995, se publicaron las siguientes vulnerabilidades:
    
    * https://pivotal.io/security/cve-2017-8045
      * RCE debido a un problema de deserialización de `org.springframework.amqp.core.Message` en Spring AMQP.
    * https://pivotal.io/security/cve-2017-8046
      * RCE debido a una deficiencia en el manejo de JSON con el método PATCH en Spring Data REST.
    
    Dado que son vulnerabilidades que fácilmente conducen a RCE, parece que tanto atacantes como investigadores de vulnerabilidades están prestando especial atención a la serialización/deserialización en Java.
    Creo que durante los próximos años seguirán apareciendo informes de vulnerabilidades relacionadas con procesos de serialización/deserialización.
    Dicho esto, al igual que con Jackson, en el desarrollo actual, donde el intercambio de datos a través de API remotas se ha vuelto algo común y las bibliotecas agilizan el desarrollo, me imagino que en muchos entornos no es realista no utilizar serialización/deserialización en absoluto, o crearla desde cero.
    Personalmente, creo que lo importante es construir una cultura y un entorno de desarrollo ágil que permita actualizar las bibliotecas lo antes posible cuando se publique una vulnerabilidad.
    
    Tenía algo que reflexionar a nivel mental sobre cómo afrontar las vulnerabilidades del middleware, las bibliotecas y los frameworks de los que dependemos, así que lo he plasmado como una reflexión a continuación.
    
    ## Reflexión
    
    Cuando vi la información de que se habían publicado S2-054 y S2-055, y que esto se debía a la vulnerabilidad de Jackson, me impactó bastante.
    Y es que unos días antes, un compañero me había preguntado: "¿Qué biblioteca recomiendas para parsear JSON en Java?", y yo, con aires de suficiencia, le había respondido: "Jackson es muy utilizado en OSS y tiene un historial probado. Como hay muchos artículos y Q&A en Google, te lo recomiendo".
    
    Yo mismo había utilizado Jackson en el desarrollo de herramientas internas de la empresa y había experimentado su conveniencia.
    Sin embargo, en ese momento no conocía CVE-2017-7525, y me sentía tranquilo porque Jackson era ampliamente utilizado en OSS y tenía muchos usuarios.
    
    Entonces, otro compañero encontró el blog de Adam Caudill y me informó de la existencia de CVE-2017-7525. Unos días después de haber recomendado Jackson con tanta seguridad, se publicó una actualización de Struts2 debido a la vulnerabilidad de Jackson. Además, la vulnerabilidad de Jackson ya había sido solucionada varios meses antes. Como ingeniero en el sector de la seguridad, no tengo excusa si se me acusa de haber descuidado la recopilación de información sobre vulnerabilidades de las bibliotecas que uso (aunque solo puedo decir que así fue).
    
    Por eso, durante los últimos días, mi estado mental fue pésimo (aumento de la presión arterial y el pulso, temblor en las manos, ganas de llorar sin estar triste, palpitaciones incesantes, etc.). Para intentar solucionarlo, decidí empezar por entender qué era CVE-2017-7525 y cuál era exactamente la situación de Jackson, y dediqué el fin de semana a investigar y redactar este artículo.
    
    Al reflexionar sobre esto, reconozco que cuando uno se dedica al desarrollo, es difícil prestar atención a la información de actualización de las bibliotecas de las que depende.
    En medio de las continuas tareas de desarrollo, es prácticamente imposible realizar una investigación completa de todas las funcionalidades y aspectos de calidad, como las vulnerabilidades, de todas las bibliotecas utilizadas.
    Por otro lado, las funcionalidades exigidas al desarrollo son cada vez mayores, y es poco realista desarrollarlas todas desde cero.
    En algún momento, es necesario "confiar" en las bibliotecas que se utilizan para agilizar el desarrollo.
    Sin embargo, también es muy difícil rastrear toda la información de actualización de las herramientas y bibliotecas utilizadas en el trabajo diario y estar atento a si incluyen correcciones de problemas de seguridad.
    Por supuesto, soy consciente de que existen servicios que, al registrar las herramientas y bibliotecas utilizadas, distribuyen información de actualización para ayudar a resolver este problema.
    
    Lo que sentí con el deterioro de mi estado mental fue que tenía un fuerte "sentimiento de autoculpabilidad y remordimiento por no haber hecho algo".
    Me estaba etiquetando negativamente a mí mismo: "A pesar de ser ingeniero de seguridad, no estaba al tanto de la información de vulnerabilidades de la biblioteca que uso...".
    Incluso los desarrolladores generales que no están relacionados con la industria de la seguridad probablemente albergan arrepentimientos y ansiedades como: "Si no hubiera propuesto Struts2 en ese momento..." o "Debo gestionar más estrictamente el ciclo de vida de las bibliotecas/frameworks (= me preocupa la situación actual en la que no lo hago)".
    
    Si intentáramos "resolver" esto de frente como un "problema", tendríamos que recopilar información sobre vulnerabilidades una por una, verificar el código fuente y las funcionalidades de las bibliotecas y frameworks que planeamos usar, investigar a fondo si se consideran estándares de facto y, después del inicio de la operación, realizar una gestión rigurosa del ciclo de vida.
    
    Sin embargo, ¿es realmente posible ese enfoque de "golpear el puente de piedra antes de cruzarlo" en los diversos entornos de desarrollo actuales?
    
    Al escribir este artículo, pensé que la era de considerar las "cosas que no se hicieron / no se pudieron hacer / no se notaron" como causas o culpables, y eliminarlas (= hacerlas posibles) como la única "solución al problema", quizás ya haya terminado.
    En una cultura así, a menos que uno sea perfecto, los desarrolladores tendrán que enfrentarse continuamente a sus propias "cosas que no hicieron, no pudieron hacer o no notaron".
    Dado que no existen personas perfectas, creo que solo aquellos con una fortaleza mental considerable podrían soportarlo.
    
    En los problemas de seguridad del software, quien realmente causa el daño es el atacante. Quien pone la situación en negativo es el atacante que explota las vulnerabilidades.
    
    La mayoría de los desarrolladores, en esencia, trabajan en el desarrollo con buena fe y seriedad. En ese punto, ya están en positivo.
    "No gestionar el ciclo de vida de las bibliotecas/frameworks" o "no recopilar ni monitorear la información de vulnerabilidades de las bibliotecas utilizadas" es simplemente algo que no se hace, y no es ni positivo ni negativo.
    Sin embargo, debido a la existencia de atacantes, que lo "no hecho" se convierta en negativo como "lo que no se pudo hacer / no se notó", ¿no es una situación demasiado triste?
    
    No se puede negar que la mentalidad de "golpear el puente de piedra antes de cruzarlo" está influenciada por la sociedad japonesa moderna y la cultura empresarial.
    De hecho, hay casos en los que se introducen vulnerabilidades como la inyección SQL, se producen daños por atacantes, y se responsabiliza a la empresa desarrolladora en los tribunales.
    También hay casos en los que la negligencia en el trabajo conduce a accidentes graves.
    
    Sin embargo, si todo eso se reduce a un problema de la "empresa desarrolladora/desarrollador", creo que el desarrollo de TI en general se vuelve tímido.
    Quien es realmente malo es el atacante que explota las vulnerabilidades.
    Si lo pensamos así, ¿no se podría decir que los desarrolladores y las empresas desarrolladoras que "no hacen / no pueden hacer / no notan" son más bien víctimas que perpetradores?
    Si es así, en lugar de señalar a las víctimas diciendo "es tu culpa por no hacer / no poder / no notar", creo firmemente que es importante tender una mano cálida con el objetivo de caminar juntos, diciendo "si haces esto, será más seguro; podemos mejorar, esforcémonos juntos", y mientras tanto, superarnos y aprovecharnos mutuamente en nuestras respectivas áreas de especialización.
    Si eso sucede, las empresas desarrolladoras y los desarrolladores podrán abordar las vulnerabilidades con tranquilidad, y luego será más fácil desarrollar activamente sobre una base segura.
    Si los entornos de desarrollo se vuelven seguros, brillantes y aumentan los desarrollos proactivos, ¿no se incrementarán los resultados innovadores y la sociedad japonesa será más próspera?
    
    Personalmente, siento firmemente que sería bueno que en el futuro se difundieran las siguientes ideas:
    
    * Desarrolladores de campo
      * "Haber usado una biblioteca con vulnerabilidades" no es negativo en sí mismo.
      * Quien lo vuelve negativo es el atacante que explota la vulnerabilidad, y también la cultura que lo evalúa como negativo.
      * El solo hecho de trabajar seriamente en el desarrollo día a día ya es suficientemente positivo.
      * La respuesta a vulnerabilidades no es un trabajo para volver a cero desde lo negativo, sino un trabajo positivo para mejorar los resultados diarios del desarrollo hacia algo más seguro.
    * Gerentes, líderes y directivos que supervisan a los desarrolladores
      * No evalúen negativamente "lo que no se hizo / no se pudo hacer / no se notó". Esa mentalidad se desvanecerá gradualmente en el futuro.
      * Dejen de tratar a los miembros que "no hicieron / no pudieron hacer / no notaron" como culpables. Ellos, y todos nosotros, somos víctimas de los atacantes que explotan las vulnerabilidades; desde ese punto de vista, estamos en la misma posición.
      * Abandonen el enfoque de resolverlo todo con "medidas perfectas".
    
    Esto implica cambiar la "forma de ver y percibir las cosas", involucrando a desarrolladores, gerentes, líderes e incluso la alta dirección, pero es evidente que es extremadamente difícil.
    En primer lugar, ¿cómo deberíamos cambiarlo?
    Yo mismo no tengo la capacidad para dar la respuesta correcta, pero creo que ahí hay una pista.
    Es decir, que quizás ya no quede más remedio que rendirse en la búsqueda de la respuesta correcta.
    Todo desarrollo de software tiene algún propósito. ¿Acaso el mundo del software no se ha vuelto tan complejo que ahora es casi imposible buscar la "respuesta correcta" para lograrlo de manera segura y segura?
    Probablemente lo que hay allí es un paradigma de desarrollo que presupone el "cambio", donde múltiples jugadores prueban y yerran a su manera, intercambian información tras obtener retroalimentación, y desde ahí se ramifican y cambian libremente.
    
    En el desarrollo de sistemas, los activos de software creados una vez se utilizan durante varios años, a veces décadas.
    Sin embargo, el software conectado a Internet, como el desarrollo web, está expuesto a entornos que cambian en cuestión de meses o años.
    Puede que las bibliotecas y frameworks utilizados en un desarrollo de hace cinco años ya no sean funcionales.
    En ese caso, en un paradigma de desarrollo que considera la biblioteca/framework inicial como la "respuesta correcta" y "fija" la versión, las desventajas superan a las ventajas.
    El mundo exterior cambia constantemente, por lo que es normal que se encuentren vulnerabilidades en las bibliotecas/frameworks que se utilizan.
    Si se fija la versión, no se puede seguir ese cambio y, como resultado, se pagan costos mentales y físicos enormes en la respuesta a vulnerabilidades.
    Por lo tanto, siento firmemente que, a largo plazo, cambiar a un paradigma de desarrollo que presuponga "poder cambiar y adaptarse al cambio" conducirá a mejores resultados.
    
    Ha sido largo, pero esto es todo.
    
    ----
    Responsable: Masahiko Sakamoto (Perteneciente al Departamento de I+D, dedicado al desarrollo de herramientas de diagnóstico de aplicaciones web de uso interno)
    * Correo: [email protected]
    * Twitter: https://twitter.com/msakamoto_sf
    * Facebook: https://www.facebook.com/masahiko.sakamoto.75
    * GitHub: https://github.com/msakamoto-sf
    
    Para cualquier opinión o consulta sobre este artículo, diríjase a Sakamoto.
    
    Descargar herramienta