Skip to content

Commit 7341d10

Browse files
committed
fix truncation
1 parent fb63569 commit 7341d10

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/XssModuleImpl.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
public class XssModuleImpl extends SinkModuleBase implements XssModule {
1515

16+
private static final int MAX_LENGTH = 500;
17+
1618
public XssModuleImpl(final Dependencies dependencies) {
1719
super(dependencies);
1820
}
@@ -61,6 +63,13 @@ public void onXss(@Nonnull CharSequence s, @Nullable String file, int line) {
6163
checkInjection(VulnerabilityType.XSS, s, new FileAndLineLocationSupplier(file, line));
6264
}
6365

66+
private static String truncate(final String s) {
67+
if (s == null || s.length() <= MAX_LENGTH) {
68+
return s;
69+
}
70+
return s.substring(0, MAX_LENGTH);
71+
}
72+
6473
private static class ClassMethodLocationSupplier implements LocationSupplier {
6574
private final String clazz;
6675
private final String method;
@@ -72,7 +81,7 @@ private ClassMethodLocationSupplier(final String clazz, final String method) {
7281

7382
@Override
7483
public Location build(final @Nullable AgentSpan span) {
75-
return Location.forSpanAndClassAndMethod(span, clazz, method);
84+
return Location.forSpanAndClassAndMethod(span, truncate(clazz), truncate(method));
7685
}
7786
}
7887

@@ -87,7 +96,7 @@ private FileAndLineLocationSupplier(final String file, final int line) {
8796

8897
@Override
8998
public Location build(@Nullable final AgentSpan span) {
90-
return Location.forSpanAndFileAndLine(span, file, line);
99+
return Location.forSpanAndFileAndLine(span, truncate(file), line);
91100
}
92101
}
93102
}

dd-smoke-tests/springboot-thymeleaf/src/main/java/datadog/smoketest/springboot/XssController.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,43 @@
55
import org.springframework.web.bind.annotation.GetMapping;
66
import org.springframework.web.bind.annotation.RequestMapping;
77
import org.springframework.web.bind.annotation.RequestParam;
8+
import org.springframework.web.bind.annotation.ResponseBody;
9+
import org.thymeleaf.context.Context;
10+
import org.thymeleaf.spring5.SpringTemplateEngine;
11+
import org.thymeleaf.templateresolver.StringTemplateResolver;
812

913
@Controller
1014
@RequestMapping("/xss")
1115
public class XssController {
1216

17+
private static final String TEMPLATE = "<p th:utext=\"${xss}\">Test!</p>";
18+
19+
private static final String BIG_TEMPLATE =
20+
new String(new char[500]).replace('\0', 'A') + "<p th:utext=\"${xss}\">Test!</p>";
21+
1322
@GetMapping("/utext")
1423
public String utext(@RequestParam(name = "string") String name, Model model) {
1524
model.addAttribute("xss", name);
1625
return "utext";
1726
}
27+
28+
@GetMapping(value = "/string-template", produces = "text/html")
29+
@ResponseBody
30+
public String stringTemplate(@RequestParam(name = "string") String name) {
31+
SpringTemplateEngine engine = new SpringTemplateEngine();
32+
engine.setTemplateResolver(new StringTemplateResolver());
33+
Context context = new Context();
34+
context.setVariable("xss", name);
35+
return engine.process(TEMPLATE, context);
36+
}
37+
38+
@GetMapping(value = "/big-string-template", produces = "text/html")
39+
@ResponseBody
40+
public String bigStringTemplate(@RequestParam(name = "string") String name) {
41+
SpringTemplateEngine engine = new SpringTemplateEngine();
42+
engine.setTemplateResolver(new StringTemplateResolver());
43+
Context context = new Context();
44+
context.setVariable("xss", name);
45+
return engine.process(BIG_TEMPLATE, context);
46+
}
1847
}

dd-smoke-tests/springboot-thymeleaf/src/test/groovy/datadog/smoketest/springboot/IastSpringBootThymeleafSmokeTest.groovy

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package datadog.smoketest.springboot
22

33
import datadog.smoketest.AbstractIastServerSmokeTest
44
import okhttp3.Request
5+
import java.net.URLEncoder
56

67
import static datadog.trace.api.config.IastConfig.IAST_DEBUG_ENABLED
78
import static datadog.trace.api.config.IastConfig.IAST_DETECTION_MODE
@@ -37,13 +38,50 @@ class IastSpringBootThymeleafSmokeTest extends AbstractIastServerSmokeTest {
3738
final request = new Request.Builder().url(url).get().build()
3839

3940
when:
40-
client.newCall(request).execute()
41+
def response = client.newCall(request).execute()
4142

4243
then:
44+
response.code() == 200
4345
hasVulnerability { vul -> vul.type == 'XSS' && vul.location.path == templateName && vul.location.line == line }
4446

4547
where:
4648
method | param |templateName| line
4749
'utext' | 'test' | 'utext' | 12
4850
}
51+
52+
void 'xss with string template returns html as template name'() {
53+
setup:
54+
final param = '<script>'
55+
final encoded = URLEncoder.encode(param, 'UTF-8')
56+
final url = "http://localhost:${httpPort}/xss/string-template?string=${encoded}"
57+
final request = new Request.Builder().url(url).get().build()
58+
59+
when:
60+
client.newCall(request).execute()
61+
62+
then:
63+
hasVulnerability { vul ->
64+
vul.type == 'XSS' &&
65+
vul.location.path == '<p th:utext="${xss}">Test!</p>' &&
66+
vul.location.line == 1
67+
}
68+
}
69+
70+
void 'xss with string template returns html as template name - truncated'() {
71+
setup:
72+
final param = '<script>'
73+
final encoded = URLEncoder.encode(param, 'UTF-8')
74+
final url = "http://localhost:${httpPort}/xss/big-string-template?string=${encoded}"
75+
final request = new Request.Builder().url(url).get().build()
76+
77+
when:
78+
client.newCall(request).execute()
79+
80+
then:
81+
hasVulnerability { vul ->
82+
vul.type == 'XSS' &&
83+
vul.location.path == 'A'*500 &&
84+
vul.location.line == 1
85+
}
86+
}
4987
}

0 commit comments

Comments
 (0)