Skip to content

Commit a76f69c

Browse files
committed
RUM: Prevent any Content-Length header from being set upon injection
1 parent c714e59 commit a76f69c

File tree

8 files changed

+114
-12
lines changed

8 files changed

+114
-12
lines changed

dd-java-agent/instrumentation/servlet/jakarta-servlet-5.0/src/main/java/datadog/trace/instrumentation/servlet5/RumHttpServletResponseWrapper.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,33 @@ public PrintWriter getWriter() throws IOException {
103103

104104
@Override
105105
public void setHeader(String name, String value) {
106-
checkForContentSecurityPolicy(name);
106+
if (shouldInject) {
107+
if (isContentLengthHeader(name)) {
108+
return;
109+
}
110+
checkForContentSecurityPolicy(name);
111+
}
107112
super.setHeader(name, value);
108113
}
109114

110115
@Override
111116
public void addHeader(String name, String value) {
112-
checkForContentSecurityPolicy(name);
117+
if (shouldInject) {
118+
if (isContentLengthHeader(name)) {
119+
return;
120+
}
121+
checkForContentSecurityPolicy(name);
122+
}
113123
super.addHeader(name, value);
114124
}
115125

126+
private boolean isContentLengthHeader(String name) {
127+
return "content-length".equalsIgnoreCase(name);
128+
}
129+
116130
private void checkForContentSecurityPolicy(String name) {
117-
if (name != null) {
118-
if (name.startsWith("Content-Security-Policy")) {
119-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected(servletVersion);
120-
}
131+
if (name != null && name.equalsIgnoreCase("content-security-policy")) {
132+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected(servletVersion);
121133
}
122134
}
123135

dd-java-agent/instrumentation/servlet/javax-servlet/javax-servlet-3.0/src/main/java/datadog/trace/instrumentation/servlet3/RumHttpServletResponseWrapper.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,33 @@ public PrintWriter getWriter() throws IOException {
122122

123123
@Override
124124
public void setHeader(String name, String value) {
125-
checkForContentSecurityPolicy(name);
125+
if (shouldInject) {
126+
if (isContentLengthHeader(name)) {
127+
return;
128+
}
129+
checkForContentSecurityPolicy(name);
130+
}
126131
super.setHeader(name, value);
127132
}
128133

129134
@Override
130135
public void addHeader(String name, String value) {
131-
checkForContentSecurityPolicy(name);
136+
if (shouldInject) {
137+
if (isContentLengthHeader(name)) {
138+
return;
139+
}
140+
checkForContentSecurityPolicy(name);
141+
}
132142
super.addHeader(name, value);
133143
}
134144

145+
private boolean isContentLengthHeader(String name) {
146+
return "content-length".equalsIgnoreCase(name);
147+
}
148+
135149
private void checkForContentSecurityPolicy(String name) {
136-
if (name != null) {
137-
if (name.startsWith("Content-Security-Policy")) {
138-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected(servletVersion);
139-
}
150+
if (name != null && name.equalsIgnoreCase("content-security-policy")) {
151+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected(servletVersion);
140152
}
141153
}
142154

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-3.1/src/latestDepTest/groovy/test/boot/SpringBootBasedTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ class SpringBootBasedTest extends HttpServerTest<ConfigurableApplicationContext>
129129
true
130130
}
131131

132+
@Override
133+
boolean testRumInjection() {
134+
true
135+
}
136+
132137
@Override
133138
Serializable expectedServerSpanRoute(ServerEndpoint endpoint) {
134139
switch (endpoint) {

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-3.1/src/latestDepTest/groovy/test/boot/TestController.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,27 @@ class TestController {
161161
}
162162
}
163163

164+
@RequestMapping(value = "/gimme-xml", produces = "text/xml")
165+
@ResponseBody
166+
String gimmeXml() {
167+
"<test/>"
168+
}
169+
170+
@RequestMapping(value = "/gimme-html", produces = "text/html")
171+
@ResponseBody
172+
String gimmeHtml() {
173+
"\n" +
174+
"<!doctype html>\n" +
175+
"<html>\n" +
176+
" <head>\n" +
177+
" <title>This is the title of the webpage!</title>\n" +
178+
" </head>\n" +
179+
" <body>\n" +
180+
" <p>This is an example paragraph. Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.</p>\n" +
181+
" </body>\n" +
182+
"</html>"
183+
}
184+
164185
@ExceptionHandler
165186
ResponseEntity handleException(Throwable throwable) {
166187
new ResponseEntity(throwable.message, HttpStatus.INTERNAL_SERVER_ERROR)

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-3.1/src/test/groovy/test/boot/SpringBootBasedTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ class SpringBootBasedTest extends HttpServerTest<ConfigurableApplicationContext>
144144
true
145145
}
146146

147+
@Override
148+
boolean testRumInjection() {
149+
true
150+
}
151+
147152
@Override
148153
void assertEndpointDiscovery(final List<?> endpoints) {
149154
final discovered = endpoints.collectEntries { [(it.method): it] } as Map<String, Endpoint>

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-3.1/src/test/groovy/test/boot/TestController.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@ class TestController {
162162
}
163163
}
164164

165+
@RequestMapping(value = "/gimme-xml", produces = "text/xml")
166+
@ResponseBody
167+
String gimmeXml() {
168+
"<test/>"
169+
}
170+
171+
@RequestMapping(value = "/gimme-html", produces = "text/html")
172+
@ResponseBody
173+
String gimmeHtml() {
174+
"\n" +
175+
"<!doctype html>\n" +
176+
"<html>\n" +
177+
" <head>\n" +
178+
" <title>This is the title of the webpage!</title>\n" +
179+
" </head>\n" +
180+
" <body>\n" +
181+
" <p>This is an example paragraph. Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.</p>\n" +
182+
" </body>\n" +
183+
"</html>"
184+
}
185+
165186
@RequestMapping(value = "/discovery",
166187
method = [RequestMethod.POST, RequestMethod.PATCH, RequestMethod.PUT],
167188
consumes = MediaType.APPLICATION_JSON_VALUE,

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/SpringBootBasedTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ class SpringBootBasedTest extends HttpServerTest<ConfigurableApplicationContext>
221221
true
222222
}
223223

224+
@Override
225+
boolean testRumInjection() {
226+
true
227+
}
228+
224229
@Override
225230
Map<String, Serializable> expectedExtraErrorInformation(ServerEndpoint endpoint) {
226231
// latest DispatcherServlet throws if no handlers have been found

dd-java-agent/instrumentation/spring/spring-webmvc/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/TestController.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,27 @@ class TestController {
151151
}
152152
}
153153

154+
@RequestMapping(value = "/gimme-xml", produces = "text/xml")
155+
@ResponseBody
156+
String gimmeXml() {
157+
"<test/>"
158+
}
159+
160+
@RequestMapping(value = "/gimme-html", produces = "text/html")
161+
@ResponseBody
162+
String gimmeHtml() {
163+
"\n" +
164+
"<!doctype html>\n" +
165+
"<html>\n" +
166+
" <head>\n" +
167+
" <title>This is the title of the webpage!</title>\n" +
168+
" </head>\n" +
169+
" <body>\n" +
170+
" <p>This is an example paragraph. Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.</p>\n" +
171+
" </body>\n" +
172+
"</html>"
173+
}
174+
154175
@ExceptionHandler
155176
ResponseEntity handleException(Throwable throwable) {
156177
new ResponseEntity(throwable.message, HttpStatus.INTERNAL_SERVER_ERROR)

0 commit comments

Comments
 (0)