@@ -5,10 +5,16 @@ import datadog.trace.agent.test.base.HttpServer
55import foo.bar.VulnerableUrlBuilder
66import okhttp3.HttpUrl
77import okhttp3.Request
8+ import org.eclipse.jetty.server.Server
9+ import org.eclipse.jetty.server.ServerConnector
10+ import org.eclipse.jetty.servlet.ServletContextHandler
11+ import org.eclipse.jetty.servlet.ServletHolder
812
9- import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
13+ import javax.servlet.http.HttpServlet
14+ import javax.servlet.http.HttpServletRequest
15+ import javax.servlet.http.HttpServletResponse
1016
11- class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer > {
17+ class IastHttpClientIntegrationTest extends IastHttpServerTest<Server > {
1218
1319 static final CLIENTS = [
1420 ' org.apache.http.impl.client.AutoRetryHttpClient' ,
@@ -20,28 +26,58 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
2026 @Override
2127 HttpServer server () {
2228 final controller = new SsrfController ()
23- return httpServer {
24- handlers {
25- prefix(' /ssrf/execute' ) {
26- final msg = controller. apacheSsrf(
27- VulnerableUrlBuilder . url(request),
28- (String ) request. getParameter(' clientClassName' ),
29- (String ) request. getParameter(' method' ),
30- (String ) request. getParameter(' requestType' ),
31- (String ) request. getParameter(' scheme' )
32- )
33- response. status(200 ). send(msg)
34- }
29+
30+ // Use _raw_ jetty API, so the jetty instrumentation is applied
31+ // (the :dd-java-agent:testing has a shadowed jetty server.)
32+ return new HttpServer () {
33+ Server jettyServer
34+ int port
35+
36+ @Override
37+ void start () {
38+ jettyServer = new Server (0 ) // 0 = random port
39+
40+ ServletContextHandler context = new ServletContextHandler (ServletContextHandler . SESSIONS )
41+ context. setContextPath(' /' )
42+ jettyServer. setHandler(context)
43+
44+ // Add servlet for the /ssrf/execute endpoint
45+ context. addServlet(new ServletHolder (new HttpServlet () {
46+ @Override
47+ protected void doGet (HttpServletRequest req , HttpServletResponse resp ) {
48+ final msg = controller. apacheSsrf(
49+ VulnerableUrlBuilder . url(req),
50+ req. getParameter(' clientClassName' ),
51+ req. getParameter(' method' ),
52+ req. getParameter(' requestType' ),
53+ req. getParameter(' scheme' )
54+ )
55+ resp. setStatus(200 )
56+ resp. writer. write(msg)
57+ }
58+ }), ' /ssrf/execute' )
59+
60+ jettyServer. start()
61+ port = ((ServerConnector ) jettyServer. connectors[0 ]). localPort
3562 }
36- }. asHttpServer()
63+
64+ @Override
65+ void stop () {
66+ jettyServer?. stop()
67+ }
68+
69+ @Override
70+ URI address () {
71+ return new URI (" http://localhost:${ port} /" )
72+ }
73+ }
3774 }
3875
3976 void ' ssrf is present: #suite' () {
4077 setup :
4178 final url = suite. url(address)
4279 final request = new Request.Builder (). url(url). get(). build()
4380
44-
4581 when :
4682 def response = client. newCall(request). execute()
4783
@@ -52,6 +88,9 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
5288 assert to != null
5389 hasVulnerability(vul -> vul. type == VulnerabilityType . SSRF && suite. evidenceMatches(vul. evidence))
5490
91+ cleanup :
92+ response?. close()
93+
5594 where :
5695 suite << createTestSuite()
5796 }
@@ -73,12 +112,12 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
73112 private List<TestSuite > createTestSuite (client , method , request , scheme ) {
74113 return TaintedTarget . values(). collect {
75114 new TestSuite (
76- description : " Tainted ${ it.name()} with ${ client} client and ${ method} method with ${ request} and ${ scheme} scheme" ,
77- executedMethod : method. name(),
78- clientImplementation : client,
79- requestType : request. name(),
80- scheme : scheme,
81- tainted : it
115+ description : " Tainted ${ it.name()} with ${ client} client and ${ method} method with ${ request} and ${ scheme} scheme" ,
116+ executedMethod : method. name(),
117+ clientImplementation : client,
118+ requestType : request. name(),
119+ scheme : scheme,
120+ tainted : it
82121 )
83122 }
84123 }
@@ -106,14 +145,14 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
106145
107146 HttpUrl url (final URI address ) {
108147 final builder = new HttpUrl.Builder ()
109- .scheme(address. getScheme())
110- .host(address. getHost())
111- .port(address. getPort())
112- .addPathSegments(' ssrf/execute' )
113- .addQueryParameter(' clientClassName' , clientImplementation)
114- .addQueryParameter(' method' , executedMethod)
115- .addQueryParameter(' requestType' , requestType)
116- .addQueryParameter(' scheme' , scheme)
148+ .scheme(address. getScheme())
149+ .host(address. getHost())
150+ .port(address. getPort())
151+ .addPathSegments(' ssrf/execute' )
152+ .addQueryParameter(' clientClassName' , clientImplementation)
153+ .addQueryParameter(' method' , executedMethod)
154+ .addQueryParameter(' requestType' , requestType)
155+ .addQueryParameter(' scheme' , scheme)
117156 tainted. addTainted(builder, this )
118157 return builder. build()
119158 }
@@ -129,7 +168,7 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
129168 }
130169
131170 private static enum TaintedTarget {
132- URL {
171+ URL {
133172 void addTainted(HttpUrl.Builder builder, TestSuite suite) {
134173 builder. addQueryParameter(' url' , suite. scheme + ' ://inexistent/test?1=1' )
135174 }
@@ -138,7 +177,7 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
138177 return assertTainted(evidence, ' url' , suite. scheme + ' ://inexistent/test?1=1' )
139178 }
140179 },
141- SCHEME {
180+ SCHEME {
142181 void addTainted(HttpUrl.Builder builder, TestSuite suite) {
143182 // already added by the test
144183 }
@@ -147,7 +186,7 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
147186 return assertTainted(evidence, ' scheme' , suite. scheme)
148187 }
149188 },
150- HOST {
189+ HOST {
151190 void addTainted(HttpUrl.Builder builder, TestSuite suite) {
152191 builder. addQueryParameter(' host' , ' inexistent' )
153192 }
@@ -156,7 +195,7 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
156195 return assertTainted(evidence, ' host' , ' inexistent' )
157196 }
158197 },
159- PATH {
198+ PATH {
160199 void addTainted(HttpUrl.Builder builder, TestSuite suite) {
161200 builder. addQueryParameter(' path' , ' /test' )
162201 }
@@ -165,7 +204,7 @@ class IastHttpClientIntegrationTest extends IastHttpServerTest<HttpServer> {
165204 return assertTainted(evidence, ' path' , ' /test' )
166205 }
167206 },
168- QUERY {
207+ QUERY {
169208 void addTainted(HttpUrl.Builder builder, TestSuite suite) {
170209 builder. addQueryParameter(' query' , ' ?1=1' )
171210 }
0 commit comments