From ae313e3a8f106052cccec1c1fffcc3b85e090e60 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Thu, 25 Apr 2024 11:23:11 +0200 Subject: [PATCH] Add XSS support for JSP --- .../servlet/request-5/build.gradle | 1 + .../jsp/JakartaJspWriterCallSite.java | 44 ++++++++++++++++++ .../JakartaJspWriterCallsiteTest.groovy | 43 +++++++++++++++++ .../foo/bar/smoketest/TestJspWriterSuite.java | 45 ++++++++++++++++++ .../servlet/jsp/JspWriterCallSite.java | 44 ++++++++++++++++++ .../JspWriterInstrumentationTest.groovy | 43 +++++++++++++++++ .../test/java/foo/bar/TestJspWriterSuite.java | 45 ++++++++++++++++++ .../springboot-jetty-jsp/build.gradle | 41 +++++++++++++++++ .../springboot/SpringbootApplication.java | 11 +++++ .../smoketest/springboot/ViewController.java | 13 ++++++ .../src/main/resources/application.properties | 4 ++ .../src/main/webapp/WEB-INF/jsp/test_xss.jsp | 11 +++++ .../springboot/IastSpringBootSmokeTest.groovy | 46 +++++++++++++++++++ .../springboot-tomcat-jsp/build.gradle | 41 +++++++++++++++++ .../springboot/SpringbootApplication.java | 11 +++++ .../smoketest/springboot/ViewController.java | 13 ++++++ .../src/main/resources/application.properties | 4 ++ .../src/main/webapp/WEB-INF/jsp/test_xss.jsp | 11 +++++ .../springboot/IastSpringBootSmokeTest.groovy | 46 +++++++++++++++++++ .../springboot/controller/ViewController.java | 13 ++++++ settings.gradle | 2 + 21 files changed, 532 insertions(+) create mode 100644 dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/jsp/JakartaJspWriterCallSite.java create mode 100644 dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaJspWriterCallsiteTest.groovy create mode 100644 dd-java-agent/instrumentation/servlet/request-5/src/test/java/foo/bar/smoketest/TestJspWriterSuite.java create mode 100644 dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/jsp/JspWriterCallSite.java create mode 100644 dd-java-agent/instrumentation/servlet/src/test/groovy/JspWriterInstrumentationTest.groovy create mode 100644 dd-java-agent/instrumentation/servlet/src/test/java/foo/bar/TestJspWriterSuite.java create mode 100644 dd-smoke-tests/springboot-jetty-jsp/build.gradle create mode 100644 dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java create mode 100644 dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java create mode 100644 dd-smoke-tests/springboot-jetty-jsp/src/main/resources/application.properties create mode 100644 dd-smoke-tests/springboot-jetty-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp create mode 100644 dd-smoke-tests/springboot-jetty-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/build.gradle create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/src/main/resources/application.properties create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp create mode 100644 dd-smoke-tests/springboot-tomcat-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy create mode 100644 dd-smoke-tests/springboot-tomcat/src/main/java/datadog/smoketest/springboot/controller/ViewController.java diff --git a/dd-java-agent/instrumentation/servlet/request-5/build.gradle b/dd-java-agent/instrumentation/servlet/request-5/build.gradle index eb0f6384ad7..949885b0359 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/build.gradle +++ b/dd-java-agent/instrumentation/servlet/request-5/build.gradle @@ -54,6 +54,7 @@ dependencies { implementation files(relocatedJavaxJar.outputs.files) compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' testImplementation group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' + testImplementation group: 'jakarta.servlet.jsp', name: 'jakarta.servlet.jsp-api', version: '3.0.0' testRuntimeOnly project(':dd-java-agent:instrumentation:iast-instrumenter') javaxClassesToRelocate project(':dd-java-agent:instrumentation:servlet-common'), { diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/jsp/JakartaJspWriterCallSite.java b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/jsp/JakartaJspWriterCallSite.java new file mode 100644 index 00000000000..cd85ce2871e --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/jsp/JakartaJspWriterCallSite.java @@ -0,0 +1,44 @@ +package datadog.trace.instrumentation.servlet5.jsp; + +import datadog.trace.agent.tooling.csi.CallSite; +import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.InstrumentationBridge; +import datadog.trace.api.iast.Sink; +import datadog.trace.api.iast.VulnerabilityTypes; +import datadog.trace.api.iast.sink.XssModule; +import javax.annotation.Nonnull; + +@Sink(VulnerabilityTypes.XSS) +@CallSite(spi = IastCallSites.class) +public class JakartaJspWriterCallSite { + + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.print(java.lang.String)") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.println(java.lang.String)") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.write(java.lang.String)") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.write(java.lang.String, int, int)") + public static void beforeStringParam(@CallSite.Argument(0) @Nonnull final String s) { + final XssModule module = InstrumentationBridge.XSS; + if (module != null) { + try { + module.onXss(s); + } catch (final Throwable e) { + module.onUnexpectedException("beforeStringParam threw", e); + } + } + } + + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.print(char[])") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.println(char[])") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.write(char[])") + @CallSite.Before("void jakarta.servlet.jsp.JspWriter.write(char[], int, int)") + public static void beforeCharArrayParam(@CallSite.Argument(0) @Nonnull final char[] buf) { + final XssModule module = InstrumentationBridge.XSS; + if (module != null) { + try { + module.onXss(buf); + } catch (final Throwable e) { + module.onUnexpectedException("beforeCharArrayParam threw", e); + } + } + } +} diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaJspWriterCallsiteTest.groovy b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaJspWriterCallsiteTest.groovy new file mode 100644 index 00000000000..8174eb9f90f --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaJspWriterCallsiteTest.groovy @@ -0,0 +1,43 @@ +import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.api.iast.InstrumentationBridge +import datadog.trace.api.iast.sink.XssModule +import foo.bar.smoketest.TestJspWriterSuite + +import jakarta.servlet.jsp.JspWriter + +class JakartaJspWriterCallsiteTest extends AgentTestRunner{ + + static final STRING = "test" + static final CHAR_ARRAY = STRING.toCharArray() + + @Override + protected void configurePreAgent() { + injectSysConfig("dd.iast.enabled", "true") + } + + void 'test JspWriter'() { + setup: + final iastModule = Mock(XssModule) + InstrumentationBridge.registerIastModule(iastModule) + final writer = Mock(JspWriter) + final suite = new TestJspWriterSuite(writer) + + when: + suite.&"$method".call(args) + + then: + 1 * iastModule.onXss(args[0]) + 0 * iastModule._ + + where: + method | args + "printTest" | [STRING] + "printlnTest" | [STRING] + "write" | [STRING] + "write" | [STRING, 0, 0] + "printTest" | [CHAR_ARRAY] + "printlnTest" | [CHAR_ARRAY] + "write" | [CHAR_ARRAY] + "write" | [CHAR_ARRAY, 0, 0] + } +} diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/test/java/foo/bar/smoketest/TestJspWriterSuite.java b/dd-java-agent/instrumentation/servlet/request-5/src/test/java/foo/bar/smoketest/TestJspWriterSuite.java new file mode 100644 index 00000000000..b68acb32ec3 --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/request-5/src/test/java/foo/bar/smoketest/TestJspWriterSuite.java @@ -0,0 +1,45 @@ +package foo.bar.smoketest; + +import jakarta.servlet.jsp.JspWriter; +import java.io.IOException; + +public class TestJspWriterSuite { + + JspWriter writer; + + public TestJspWriterSuite(final JspWriter writer) { + this.writer = writer; + } + + public void printlnTest(char x[]) throws IOException { + writer.println(x); + } + + public void printlnTest(String x) throws IOException { + writer.println(x); + } + + public void printTest(char s[]) throws IOException { + writer.print(s); + } + + public void printTest(String s) throws IOException { + writer.print(s); + } + + public void write(char s[]) throws IOException { + writer.write(s); + } + + public void write(String s) throws IOException { + writer.write(s); + } + + public void write(String s, int i, int j) throws IOException { + writer.write(s, i, j); + } + + public void write(char s[], int i, int j) throws IOException { + writer.write(s, i, j); + } +} diff --git a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/jsp/JspWriterCallSite.java b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/jsp/JspWriterCallSite.java new file mode 100644 index 00000000000..7c964e7cf1a --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/jsp/JspWriterCallSite.java @@ -0,0 +1,44 @@ +package datadog.trace.instrumentation.servlet.jsp; + +import datadog.trace.agent.tooling.csi.CallSite; +import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.InstrumentationBridge; +import datadog.trace.api.iast.Sink; +import datadog.trace.api.iast.VulnerabilityTypes; +import datadog.trace.api.iast.sink.XssModule; +import javax.annotation.Nonnull; + +@Sink(VulnerabilityTypes.XSS) +@CallSite(spi = IastCallSites.class) +public class JspWriterCallSite { + + @CallSite.Before("void javax.servlet.jsp.JspWriter.print(java.lang.String)") + @CallSite.Before("void javax.servlet.jsp.JspWriter.println(java.lang.String)") + @CallSite.Before("void javax.servlet.jsp.JspWriter.write(java.lang.String)") + @CallSite.Before("void javax.servlet.jsp.JspWriter.write(java.lang.String, int, int)") + public static void beforeStringParam(@CallSite.Argument(0) @Nonnull final String s) { + final XssModule module = InstrumentationBridge.XSS; + if (module != null) { + try { + module.onXss(s); + } catch (final Throwable e) { + module.onUnexpectedException("beforeStringParam threw", e); + } + } + } + + @CallSite.Before("void javax.servlet.jsp.JspWriter.print(char[])") + @CallSite.Before("void javax.servlet.jsp.JspWriter.println(char[])") + @CallSite.Before("void javax.servlet.jsp.JspWriter.write(char[])") + @CallSite.Before("void javax.servlet.jsp.JspWriter.write(char[], int, int)") + public static void beforeCharArrayParam(@CallSite.Argument(0) @Nonnull final char[] buf) { + final XssModule module = InstrumentationBridge.XSS; + if (module != null) { + try { + module.onXss(buf); + } catch (final Throwable e) { + module.onUnexpectedException("beforeCharArrayParam threw", e); + } + } + } +} diff --git a/dd-java-agent/instrumentation/servlet/src/test/groovy/JspWriterInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet/src/test/groovy/JspWriterInstrumentationTest.groovy new file mode 100644 index 00000000000..68e04ef9107 --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/src/test/groovy/JspWriterInstrumentationTest.groovy @@ -0,0 +1,43 @@ +import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.api.iast.InstrumentationBridge +import datadog.trace.api.iast.sink.XssModule +import foo.bar.TestJspWriterSuite + +import javax.servlet.jsp.JspWriter + +class JspWriterInstrumentationTest extends AgentTestRunner{ + + static final STRING = "test" + static final CHAR_ARRAY = STRING.toCharArray() + + @Override + protected void configurePreAgent() { + injectSysConfig("dd.iast.enabled", "true") + } + + void 'test JspWriter'() { + setup: + final iastModule = Mock(XssModule) + InstrumentationBridge.registerIastModule(iastModule) + final writer = Mock(JspWriter) + final suite = new TestJspWriterSuite(writer) + + when: + suite.&"$method".call(args) + + then: + 1 * iastModule.onXss(args[0]) + 0 * iastModule._ + + where: + method | args + "printTest" | [STRING] + "printlnTest" | [STRING] + "write" | [STRING] + "write" | [STRING, 0, 0] + "printTest" | [CHAR_ARRAY] + "printlnTest" | [CHAR_ARRAY] + "write" | [CHAR_ARRAY] + "write" | [CHAR_ARRAY, 0, 0] + } +} diff --git a/dd-java-agent/instrumentation/servlet/src/test/java/foo/bar/TestJspWriterSuite.java b/dd-java-agent/instrumentation/servlet/src/test/java/foo/bar/TestJspWriterSuite.java new file mode 100644 index 00000000000..212baa095ad --- /dev/null +++ b/dd-java-agent/instrumentation/servlet/src/test/java/foo/bar/TestJspWriterSuite.java @@ -0,0 +1,45 @@ +package foo.bar; + +import java.io.IOException; +import javax.servlet.jsp.JspWriter; + +public class TestJspWriterSuite { + + JspWriter writer; + + public TestJspWriterSuite(final JspWriter writer) { + this.writer = writer; + } + + public void printlnTest(char x[]) throws IOException { + writer.println(x); + } + + public void printlnTest(String x) throws IOException { + writer.println(x); + } + + public void printTest(char s[]) throws IOException { + writer.print(s); + } + + public void printTest(String s) throws IOException { + writer.print(s); + } + + public void write(char s[]) throws IOException { + writer.write(s); + } + + public void write(String s) throws IOException { + writer.write(s); + } + + public void write(String s, int i, int j) throws IOException { + writer.write(s, i, j); + } + + public void write(char s[], int i, int j) throws IOException { + writer.write(s, i, j); + } +} diff --git a/dd-smoke-tests/springboot-jetty-jsp/build.gradle b/dd-smoke-tests/springboot-jetty-jsp/build.gradle new file mode 100644 index 00000000000..a953ed4adc1 --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/build.gradle @@ -0,0 +1,41 @@ +plugins { + id 'java' + id 'war' + id 'org.springframework.boot' version '2.7.15' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'java-test-fixtures' +} + +apply from: "$rootDir/gradle/java.gradle" +description = 'SpringBoot Jetty JSP Smoke Tests.' + +java { + sourceCompatibility = '1.8' +} + +repositories { + mavenCentral() +} + +sourceSets { + main { + resources.srcDir("src/main/webapp") + } +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + + runtimeOnly("javax.servlet:jstl") + runtimeOnly("org.apache.tomcat.embed:tomcat-embed-jasper") + + providedRuntime("org.springframework.boot:spring-boot-starter-jetty") + + testImplementation project(':dd-smoke-tests') + testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) +} + +tasks.withType(Test).configureEach { + dependsOn "war", "bootWar" + jvmArgs "-Ddatadog.smoketest.springboot.war.path=${tasks.bootWar.archiveFile.get().getAsFile()}" +} diff --git a/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java b/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java new file mode 100644 index 00000000000..2b4e4de452a --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java @@ -0,0 +1,11 @@ +package datadog.smoketest.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringbootApplication { + public static void main(String[] args) { + SpringApplication.run(SpringbootApplication.class, args); + } +} diff --git a/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java b/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java new file mode 100644 index 00000000000..2094d2e3dbe --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java @@ -0,0 +1,13 @@ +package datadog.smoketest.springboot; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ViewController { + + @GetMapping("/test_xss_in_jsp") + public String test() { + return "test_xss"; + } +} diff --git a/dd-smoke-tests/springboot-jetty-jsp/src/main/resources/application.properties b/dd-smoke-tests/springboot-jetty-jsp/src/main/resources/application.properties new file mode 100644 index 00000000000..3e12a2b91c1 --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/src/main/resources/application.properties @@ -0,0 +1,4 @@ +logging.level.root=WARN +spring.application.name=sp +spring.mvc.view.prefix=/WEB-INF/jsp/ +spring.mvc.view.suffix=.jsp diff --git a/dd-smoke-tests/springboot-jetty-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp b/dd-smoke-tests/springboot-jetty-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp new file mode 100644 index 00000000000..410f58771cd --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp @@ -0,0 +1,11 @@ +<%@ page contentType="text/html;charset=UTF-8" %> + + +Test XSS + + + <% String test = request.getParameter("test");%> +

Test Page

+

Test parameter: <%=test%>

+ + diff --git a/dd-smoke-tests/springboot-jetty-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy b/dd-smoke-tests/springboot-jetty-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy new file mode 100644 index 00000000000..3f9277ce834 --- /dev/null +++ b/dd-smoke-tests/springboot-jetty-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy @@ -0,0 +1,46 @@ +package datadog.smoketest.springboot + +import datadog.smoketest.AbstractIastServerSmokeTest +import okhttp3.Request +import okhttp3.Response + +import static datadog.trace.api.config.IastConfig.IAST_DEBUG_ENABLED +import static datadog.trace.api.config.IastConfig.IAST_DETECTION_MODE +import static datadog.trace.api.config.IastConfig.IAST_ENABLED + +class IastSpringBootSmokeTest extends AbstractIastServerSmokeTest { + + @Override + ProcessBuilder createProcessBuilder() { + String springBootWar = System.getProperty('datadog.smoketest.springboot.war.path') + + List command = [] + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll([ + withSystemProperty(IAST_ENABLED, true), + withSystemProperty(IAST_DETECTION_MODE, 'FULL'), + withSystemProperty(IAST_DEBUG_ENABLED, true) + ]) + command.addAll((String[]) ['-jar', springBootWar, "--server.port=${httpPort}"]) + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + // Spring will print all environment variables to the log, which may pollute it and affect log assertions. + processBuilder.environment().clear() + return processBuilder + } + + void 'find xss in jsp'() { + given: + String url = "http://localhost:${httpPort}/test_xss_in_jsp?test=thisCouldBeDangerous" + + when: + Response response = client.newCall(new Request.Builder().url(url).get().build()).execute() + + then: + response.successful + hasVulnerability { vul -> + vul.type == 'XSS' + } + } +} diff --git a/dd-smoke-tests/springboot-tomcat-jsp/build.gradle b/dd-smoke-tests/springboot-tomcat-jsp/build.gradle new file mode 100644 index 00000000000..31e6db4bebd --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/build.gradle @@ -0,0 +1,41 @@ +plugins { + id 'java' + id 'war' + id 'org.springframework.boot' version '2.7.15' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'java-test-fixtures' +} + +apply from: "$rootDir/gradle/java.gradle" +description = 'SpringBoot Tomcat JSP Smoke Tests.' + +java { + sourceCompatibility = '1.8' +} + +repositories { + mavenCentral() +} + +sourceSets { + main { + resources.srcDir("src/main/webapp") + } +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + + runtimeOnly("javax.servlet:jstl") + runtimeOnly("org.apache.tomcat.embed:tomcat-embed-jasper") + + providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") + + testImplementation project(':dd-smoke-tests') + testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) +} + +tasks.withType(Test).configureEach { + dependsOn "war", "bootWar" + jvmArgs "-Ddatadog.smoketest.springboot.war.path=${tasks.bootWar.archiveFile.get().getAsFile()}" +} diff --git a/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java b/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java new file mode 100644 index 00000000000..2b4e4de452a --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/SpringbootApplication.java @@ -0,0 +1,11 @@ +package datadog.smoketest.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringbootApplication { + public static void main(String[] args) { + SpringApplication.run(SpringbootApplication.class, args); + } +} diff --git a/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java b/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java new file mode 100644 index 00000000000..2094d2e3dbe --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/src/main/java/datadog/smoketest/springboot/ViewController.java @@ -0,0 +1,13 @@ +package datadog.smoketest.springboot; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ViewController { + + @GetMapping("/test_xss_in_jsp") + public String test() { + return "test_xss"; + } +} diff --git a/dd-smoke-tests/springboot-tomcat-jsp/src/main/resources/application.properties b/dd-smoke-tests/springboot-tomcat-jsp/src/main/resources/application.properties new file mode 100644 index 00000000000..fbd10e4c1ba --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/src/main/resources/application.properties @@ -0,0 +1,4 @@ +logging.level.root=WARN +spring.application.name=springboot-tomcat-jsp +spring.mvc.view.prefix=/WEB-INF/jsp/ +spring.mvc.view.suffix=.jsp diff --git a/dd-smoke-tests/springboot-tomcat-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp b/dd-smoke-tests/springboot-tomcat-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp new file mode 100644 index 00000000000..410f58771cd --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/src/main/webapp/WEB-INF/jsp/test_xss.jsp @@ -0,0 +1,11 @@ +<%@ page contentType="text/html;charset=UTF-8" %> + + +Test XSS + + + <% String test = request.getParameter("test");%> +

Test Page

+

Test parameter: <%=test%>

+ + diff --git a/dd-smoke-tests/springboot-tomcat-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy b/dd-smoke-tests/springboot-tomcat-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy new file mode 100644 index 00000000000..3f9277ce834 --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat-jsp/src/test/groovy/datadog/smoketest/springboot/IastSpringBootSmokeTest.groovy @@ -0,0 +1,46 @@ +package datadog.smoketest.springboot + +import datadog.smoketest.AbstractIastServerSmokeTest +import okhttp3.Request +import okhttp3.Response + +import static datadog.trace.api.config.IastConfig.IAST_DEBUG_ENABLED +import static datadog.trace.api.config.IastConfig.IAST_DETECTION_MODE +import static datadog.trace.api.config.IastConfig.IAST_ENABLED + +class IastSpringBootSmokeTest extends AbstractIastServerSmokeTest { + + @Override + ProcessBuilder createProcessBuilder() { + String springBootWar = System.getProperty('datadog.smoketest.springboot.war.path') + + List command = [] + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll([ + withSystemProperty(IAST_ENABLED, true), + withSystemProperty(IAST_DETECTION_MODE, 'FULL'), + withSystemProperty(IAST_DEBUG_ENABLED, true) + ]) + command.addAll((String[]) ['-jar', springBootWar, "--server.port=${httpPort}"]) + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + // Spring will print all environment variables to the log, which may pollute it and affect log assertions. + processBuilder.environment().clear() + return processBuilder + } + + void 'find xss in jsp'() { + given: + String url = "http://localhost:${httpPort}/test_xss_in_jsp?test=thisCouldBeDangerous" + + when: + Response response = client.newCall(new Request.Builder().url(url).get().build()).execute() + + then: + response.successful + hasVulnerability { vul -> + vul.type == 'XSS' + } + } +} diff --git a/dd-smoke-tests/springboot-tomcat/src/main/java/datadog/smoketest/springboot/controller/ViewController.java b/dd-smoke-tests/springboot-tomcat/src/main/java/datadog/smoketest/springboot/controller/ViewController.java new file mode 100644 index 00000000000..ca76401f875 --- /dev/null +++ b/dd-smoke-tests/springboot-tomcat/src/main/java/datadog/smoketest/springboot/controller/ViewController.java @@ -0,0 +1,13 @@ +package datadog.smoketest.springboot.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ViewController { + + @GetMapping("/test_xss_in_jsp") + public String test() { + return "test_xss"; + } +} diff --git a/settings.gradle b/settings.gradle index f06ac6a9cae..febc8f95b65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -128,11 +128,13 @@ include ':dd-smoke-tests:spring-boot-rabbit' include ':dd-smoke-tests:spring-security' include ':dd-smoke-tests:springboot' include ':dd-smoke-tests:springboot-grpc' +include ':dd-smoke-tests:springboot-jetty-jsp' include ':dd-smoke-tests:springboot-mongo' include ':dd-smoke-tests:springboot-openliberty-20' include ':dd-smoke-tests:springboot-openliberty-23' include ':dd-smoke-tests:springboot-thymeleaf' include ':dd-smoke-tests:springboot-tomcat' +include ':dd-smoke-tests:springboot-tomcat-jsp' include ':dd-smoke-tests:vertx-3.4' include ':dd-smoke-tests:vertx-3.9' include ':dd-smoke-tests:vertx-3.9-resteasy'