From 7a107cc24a834ef1e58ec72d746db8d8cf78ab7c Mon Sep 17 00:00:00 2001 From: Clara Poncet Date: Tue, 4 Aug 2026 16:47:15 +0200 Subject: [PATCH 1/4] add IAST code injection tests for java --- manifests/java.yml | 14 ++++++++-- utils/build/docker/java/akka-http/pom.xml | 5 ++++ .../com/datadoghq/akka_http/IastRoutes.scala | 13 ++++++++++ utils/build/docker/java/iast-common/pom.xml | 6 +++++ .../iast/utils/CodeInjectionExamples.java | 26 +++++++++++++++++++ .../build/docker/java/jersey-grizzly2/pom.xml | 5 ++++ .../datadoghq/jersey/IastSinkResource.java | 13 ++++++++++ .../build/docker/java/resteasy-netty3/pom.xml | 5 ++++ .../datadoghq/resteasy/IastSinkResource.java | 13 ++++++++++ utils/build/docker/java/spring-boot/pom.xml | 5 ++++ .../system_tests/springboot/AppSecIast.java | 13 ++++++++++ utils/build/docker/java/vertx3/pom.xml | 5 ++++ .../iast/routes/IastSinkRouteProvider.java | 9 +++++++ utils/build/docker/java/vertx4/pom.xml | 5 ++++ .../iast/routes/IastSinkRouteProvider.java | 9 +++++++ 15 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 utils/build/docker/java/iast-common/src/main/java/com/datadoghq/system_tests/iast/utils/CodeInjectionExamples.java diff --git a/manifests/java.yml b/manifests/java.yml index 7ec6629aa7a..a0646a720df 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -307,9 +307,19 @@ manifest: tests/appsec/api_security_testing/test_normalized_route.py::Test_NormalizedRoute: missing_feature tests/appsec/api_security_testing/test_normalized_route.py::Test_NormalizedRouteMultiParamsInSegment: missing_feature tests/appsec/api_security_testing/test_normalized_route.py::Test_NormalizedRouteOptionalParams: missing_feature - tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection: missing_feature + tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection: + - weblog_declaration: + "*": v1.65.0-SNAPSHOT + play: incomplete_test_app (endpoint not implemented) + ratpack: incomplete_test_app (endpoint not implemented) + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection_ExtendedLocation: missing_feature - tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection_StackTrace: missing_feature + tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection_StackTrace: + - weblog_declaration: + "*": v1.65.0-SNAPSHOT + play: incomplete_test_app (endpoint not implemented) + ratpack: incomplete_test_app (endpoint not implemented) + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) tests/appsec/iast/sink/test_command_injection.py::TestCommandInjection: - weblog_declaration: "*": v1.1.0 diff --git a/utils/build/docker/java/akka-http/pom.xml b/utils/build/docker/java/akka-http/pom.xml index 7629762bad7..a581df9ca9b 100644 --- a/utils/build/docker/java/akka-http/pom.xml +++ b/utils/build/docker/java/akka-http/pom.xml @@ -102,6 +102,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/IastRoutes.scala b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/IastRoutes.scala index e8eeef9ffa1..eec5ef242d2 100644 --- a/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/IastRoutes.scala +++ b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/IastRoutes.scala @@ -12,6 +12,7 @@ object IastRoutes { private val superSecretAccessKey = "insecure" private val cmd = new CmdExamples() + private val codeInjection = new CodeInjectionExamples() private val crypto = new CryptoExamples() private val ldap = new LDAPExamples(ldapContext) private val path_ = new PathExamples() @@ -79,6 +80,18 @@ object IastRoutes { } } } ~ + path("code_injection" / "test_insecure") { + post { + paramOrFormField("code") { code => + complete(codeInjection.insecureCodeInjection(code)) + } + } + } ~ + path("code_injection" / "test_secure") { + post { + complete(codeInjection.secureCodeInjection()) + } + } ~ pathPrefix("xpathi") { post { path("test_insecure") { diff --git a/utils/build/docker/java/iast-common/pom.xml b/utils/build/docker/java/iast-common/pom.xml index a26dc2d1aa1..88d5ab830e7 100644 --- a/utils/build/docker/java/iast-common/pom.xml +++ b/utils/build/docker/java/iast-common/pom.xml @@ -58,6 +58,12 @@ 1.6.2 true + + org.apache-extras.beanshell + bsh + 2.0b6 + true + diff --git a/utils/build/docker/java/iast-common/src/main/java/com/datadoghq/system_tests/iast/utils/CodeInjectionExamples.java b/utils/build/docker/java/iast-common/src/main/java/com/datadoghq/system_tests/iast/utils/CodeInjectionExamples.java new file mode 100644 index 00000000000..04f0af78563 --- /dev/null +++ b/utils/build/docker/java/iast-common/src/main/java/com/datadoghq/system_tests/iast/utils/CodeInjectionExamples.java @@ -0,0 +1,26 @@ +package com.datadoghq.system_tests.iast.utils; + +import bsh.EvalError; +import bsh.Interpreter; +import java.lang.reflect.UndeclaredThrowableException; + +public class CodeInjectionExamples { + + public String insecureCodeInjection(final String code) { + try { + new Interpreter().eval(code); + return "Code injection insecure"; + } catch (EvalError e) { + throw new UndeclaredThrowableException(e); + } + } + + public String secureCodeInjection() { + try { + new Interpreter().eval("1+2"); + return "Code injection secure"; + } catch (EvalError e) { + throw new UndeclaredThrowableException(e); + } + } +} diff --git a/utils/build/docker/java/jersey-grizzly2/pom.xml b/utils/build/docker/java/jersey-grizzly2/pom.xml index 5f27b597c48..01fe9f9030b 100644 --- a/utils/build/docker/java/jersey-grizzly2/pom.xml +++ b/utils/build/docker/java/jersey-grizzly2/pom.xml @@ -98,6 +98,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/IastSinkResource.java b/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/IastSinkResource.java index 895e2963b86..13dda043a24 100644 --- a/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/IastSinkResource.java +++ b/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/IastSinkResource.java @@ -20,6 +20,7 @@ public class IastSinkResource { private final SqlExamples sql = new SqlExamples(DATA_SOURCE) ; private final LDAPExamples ldap = new LDAPExamples(LDAP_CONTEXT); private final CmdExamples cmd = new CmdExamples(); + private final CodeInjectionExamples codeInjection = new CodeInjectionExamples(); private final PathExamples path = new PathExamples(); private final SsrfExamples ssrf = new SsrfExamples(); private final WeakRandomnessExamples weakRandomness = new WeakRandomnessExamples(); @@ -81,6 +82,18 @@ public String insecureCmd(@FormParam("cmd") final String cmd) { return this.cmd.insecureCmd(cmd); } + @POST + @Path("/code_injection/test_insecure") + public String insecureCodeInjection(@FormParam("code") final String code) { + return this.codeInjection.insecureCodeInjection(code); + } + + @POST + @Path("/code_injection/test_secure") + public String secureCodeInjection() { + return this.codeInjection.secureCodeInjection(); + } + @POST @Path("/ldapi/test_insecure") public String insecureLDAP(@FormParam("username") final String username, @FormParam("password") final String password) { diff --git a/utils/build/docker/java/resteasy-netty3/pom.xml b/utils/build/docker/java/resteasy-netty3/pom.xml index c9a22c03f8f..24802f91323 100644 --- a/utils/build/docker/java/resteasy-netty3/pom.xml +++ b/utils/build/docker/java/resteasy-netty3/pom.xml @@ -96,6 +96,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/IastSinkResource.java b/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/IastSinkResource.java index 1f2b8495949..4625ef86ebb 100644 --- a/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/IastSinkResource.java +++ b/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/IastSinkResource.java @@ -23,6 +23,7 @@ public class IastSinkResource { private final SqlExamples sql = new SqlExamples(DATA_SOURCE) ; private final LDAPExamples ldap = new LDAPExamples(LDAP_CONTEXT); private final CmdExamples cmd = new CmdExamples(); + private final CodeInjectionExamples codeInjection = new CodeInjectionExamples(); private final PathExamples path = new PathExamples(); private final SsrfExamples ssrf = new SsrfExamples(); private final WeakRandomnessExamples weakRandomness = new WeakRandomnessExamples(); @@ -84,6 +85,18 @@ public String insecureCmd(@FormParam("cmd") final String cmd) { return this.cmd.insecureCmd(cmd); } + @POST + @Path("/code_injection/test_insecure") + public String insecureCodeInjection(@FormParam("code") final String code) { + return this.codeInjection.insecureCodeInjection(code); + } + + @POST + @Path("/code_injection/test_secure") + public String secureCodeInjection() { + return this.codeInjection.secureCodeInjection(); + } + @POST @Path("/ldapi/test_insecure") public String insecureLDAP(@FormParam("username") final String username, @FormParam("password") final String password) { diff --git a/utils/build/docker/java/spring-boot/pom.xml b/utils/build/docker/java/spring-boot/pom.xml index 706db3ce30d..701f29e2a7c 100644 --- a/utils/build/docker/java/spring-boot/pom.xml +++ b/utils/build/docker/java/spring-boot/pom.xml @@ -223,6 +223,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/AppSecIast.java b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/AppSecIast.java index cbd46684171..331a3fff22a 100644 --- a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/AppSecIast.java +++ b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/AppSecIast.java @@ -45,6 +45,7 @@ public class AppSecIast { private final ReflectionExamples reflectionExamples; private final DeserializationExamples deserializationExamples; private final EmailExamples emailExamples; + private final CodeInjectionExamples codeInjectionExamples; public AppSecIast(final DataSource dataSource) { @@ -60,6 +61,7 @@ public AppSecIast(final DataSource dataSource) { this.reflectionExamples = new ReflectionExamples(); this.deserializationExamples = new DeserializationExamples(); this.emailExamples = new EmailExamples(); + this.codeInjectionExamples = new CodeInjectionExamples(); } @RequestMapping("/hardcoded_secrets/test_insecure") @@ -257,6 +259,17 @@ String secureXPath(final ServletRequest request) { return "XPath secure"; } + @PostMapping("/code_injection/test_insecure") + String insecureCodeInjection(final ServletRequest request) { + final String code = request.getParameter("code"); + return codeInjectionExamples.insecureCodeInjection(code); + } + + @PostMapping("/code_injection/test_secure") + String secureCodeInjection(final ServletRequest request) { + return codeInjectionExamples.secureCodeInjection(); + } + @GetMapping("/trust-boundary-violation/test_insecure") public String trustBoundaryViolationInSecureSpringBoot(final HttpServletRequest request) { String paramValue = request.getParameter("username"); diff --git a/utils/build/docker/java/vertx3/pom.xml b/utils/build/docker/java/vertx3/pom.xml index 0aca843b1fd..c683ecc9f14 100644 --- a/utils/build/docker/java/vertx3/pom.xml +++ b/utils/build/docker/java/vertx3/pom.xml @@ -80,6 +80,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/iast/routes/IastSinkRouteProvider.java b/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/iast/routes/IastSinkRouteProvider.java index 46f22b1c459..05d64dcd617 100644 --- a/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/iast/routes/IastSinkRouteProvider.java +++ b/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/iast/routes/IastSinkRouteProvider.java @@ -24,6 +24,7 @@ public IastSinkRouteProvider(final DataSource dataSource, final InitialDirContex public void accept(final Router router) { final String superSecretAccessKey = "insecure"; final CmdExamples cmd = new CmdExamples(); + final CodeInjectionExamples codeInjection = new CodeInjectionExamples(); final CryptoExamples crypto = new CryptoExamples(); final LDAPExamples ldap = new LDAPExamples(ldapContext); final PathExamples path = new PathExamples(); @@ -77,6 +78,14 @@ public void accept(final Router router) { final String cmdParam = request.getParam("cmd"); ctx.response().end(cmd.insecureCmd(cmdParam)); }); + router.post("/iast/code_injection/test_insecure").handler(ctx -> { + final HttpServerRequest request = ctx.request(); + final String codeParam = request.getParam("code"); + ctx.response().end(codeInjection.insecureCodeInjection(codeParam)); + }); + router.post("/iast/code_injection/test_secure").handler(ctx -> + ctx.response().end(codeInjection.secureCodeInjection()) + ); router.post("/iast/path_traversal/test_insecure").handler(ctx -> { final HttpServerRequest request = ctx.request(); final String pathParam = request.getParam("path"); diff --git a/utils/build/docker/java/vertx4/pom.xml b/utils/build/docker/java/vertx4/pom.xml index 89ffb29037f..8fac4fd8a3c 100644 --- a/utils/build/docker/java/vertx4/pom.xml +++ b/utils/build/docker/java/vertx4/pom.xml @@ -80,6 +80,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/iast/routes/IastSinkRouteProvider.java b/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/iast/routes/IastSinkRouteProvider.java index 3e171d1ae0f..a6706ad641b 100644 --- a/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/iast/routes/IastSinkRouteProvider.java +++ b/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/iast/routes/IastSinkRouteProvider.java @@ -24,6 +24,7 @@ public IastSinkRouteProvider(final DataSource dataSource, final InitialDirContex public void accept(final Router router) { final String superSecretAccessKey = "insecure"; final CmdExamples cmd = new CmdExamples(); + final CodeInjectionExamples codeInjection = new CodeInjectionExamples(); final CryptoExamples crypto = new CryptoExamples(); final LDAPExamples ldap = new LDAPExamples(ldapContext); final PathExamples path = new PathExamples(); @@ -76,6 +77,14 @@ public void accept(final Router router) { final String cmdParam = request.getParam("cmd"); ctx.response().end(cmd.insecureCmd(cmdParam)); }); + router.post("/iast/code_injection/test_insecure").handler(ctx -> { + final HttpServerRequest request = ctx.request(); + final String codeParam = request.getParam("code"); + ctx.response().end(codeInjection.insecureCodeInjection(codeParam)); + }); + router.post("/iast/code_injection/test_secure").handler(ctx -> + ctx.response().end(codeInjection.secureCodeInjection()) + ); router.post("/iast/path_traversal/test_insecure").handler(ctx -> { final HttpServerRequest request = ctx.request(); final String pathParam = request.getParam("path"); From 8559e023b4860ad2c2fec93a1535078442a3f7b7 Mon Sep 17 00:00:00 2001 From: Clara Poncet Date: Tue, 4 Aug 2026 17:27:03 +0200 Subject: [PATCH 2/4] fix(java): restore bsh dependency for play and ratpack weblogs Co-Authored-By: Claude Opus 4.8 --- utils/build/docker/java/play/pom.xml | 5 +++++ utils/build/docker/java/ratpack/pom.xml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/utils/build/docker/java/play/pom.xml b/utils/build/docker/java/play/pom.xml index 03989ef1ef2..60444790cac 100644 --- a/utils/build/docker/java/play/pom.xml +++ b/utils/build/docker/java/play/pom.xml @@ -87,6 +87,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api diff --git a/utils/build/docker/java/ratpack/pom.xml b/utils/build/docker/java/ratpack/pom.xml index 85ec60a7197..bf8465d8382 100644 --- a/utils/build/docker/java/ratpack/pom.xml +++ b/utils/build/docker/java/ratpack/pom.xml @@ -71,6 +71,11 @@ commons-lang3 3.17.0 + + org.apache-extras.beanshell + bsh + 2.0b6 + javax.mail javax.mail-api From 2dac0de6166fda08a3d341635f03a85716f0b685 Mon Sep 17 00:00:00 2001 From: Clara Poncet Date: Wed, 5 Aug 2026 11:50:34 +0200 Subject: [PATCH 3/4] upgrade minimum tracer version --- manifests/java.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/java.yml b/manifests/java.yml index a0646a720df..d17f87a7c18 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -309,14 +309,14 @@ manifest: tests/appsec/api_security_testing/test_normalized_route.py::Test_NormalizedRouteOptionalParams: missing_feature tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection: - weblog_declaration: - "*": v1.65.0-SNAPSHOT + "*": v1.66.0-SNAPSHOT play: incomplete_test_app (endpoint not implemented) ratpack: incomplete_test_app (endpoint not implemented) spring-boot-3-native: irrelevant (GraalVM. Tracing support only) tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection_ExtendedLocation: missing_feature tests/appsec/iast/sink/test_code_injection.py::TestCodeInjection_StackTrace: - weblog_declaration: - "*": v1.65.0-SNAPSHOT + "*": v1.66.0-SNAPSHOT play: incomplete_test_app (endpoint not implemented) ratpack: incomplete_test_app (endpoint not implemented) spring-boot-3-native: irrelevant (GraalVM. Tracing support only) From 89915c1c86fc743e6b3c2bada17e144eea470183 Mon Sep 17 00:00:00 2001 From: Clara Poncet Date: Wed, 5 Aug 2026 17:10:27 +0200 Subject: [PATCH 4/4] fix(java): add bsh dependency to java_otel spring-boot weblog Co-Authored-By: Claude Opus 4.8 --- utils/build/docker/java_otel/spring-boot/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utils/build/docker/java_otel/spring-boot/pom.xml b/utils/build/docker/java_otel/spring-boot/pom.xml index 001fead0d76..a1170704dc6 100644 --- a/utils/build/docker/java_otel/spring-boot/pom.xml +++ b/utils/build/docker/java_otel/spring-boot/pom.xml @@ -14,6 +14,11 @@ ${packaging.type} + + org.apache-extras.beanshell + bsh + 2.0b6 + org.springframework.boot spring-boot-starter-json