Skip to content

Commit 9023c3a

Browse files
authored
Move taint methods from WebModule to PropagationModule (first batch) (#5527)
* Replace WebModule#onParameterValue with PropagationModule#taint * Replace WebModule#onPathParameterValue with PropagationModule#taint * Replace WebModule#onHeaderValue with PropagationModule#taint * Replace WebModule#onCookieValue with PropagationModule#taint * Replace WebModule#onQueryString with PropagationModule#taint * Replace WebModule#onRequest*Parameter with PropagationModule#taint * Replace WebModule#onInjectedParameter with PropagationModule#taint * Remove unused WebModuleImpl#onNamed method
1 parent 8bc4640 commit 9023c3a

File tree

49 files changed

+378
-557
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+378
-557
lines changed

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/PropagationModuleImpl.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static com.datadog.iast.taint.Tainteds.canBeTainted;
44

5+
import com.datadog.iast.IastRequestContext;
56
import com.datadog.iast.model.Range;
67
import com.datadog.iast.model.Source;
78
import com.datadog.iast.taint.TaintedObject;
@@ -132,6 +133,33 @@ public void taintIfAnyInputIsTainted(
132133
}
133134
}
134135

136+
@Override
137+
public void taint(final byte source, @Nullable final String name, @Nullable final String value) {
138+
if (!canBeTainted(value)) {
139+
return;
140+
}
141+
final IastRequestContext ctx = IastRequestContext.get();
142+
if (ctx == null) {
143+
return;
144+
}
145+
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
146+
taintedObjects.taintInputString(value, new Source(source, name, value));
147+
}
148+
149+
@Override
150+
public void taint(
151+
@Nullable final Object ctx_,
152+
final byte source,
153+
@Nullable final String name,
154+
@Nullable final String value) {
155+
if (ctx_ == null || !canBeTainted(value)) {
156+
return;
157+
}
158+
final IastRequestContext ctx = (IastRequestContext) ctx_;
159+
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
160+
taintedObjects.taintInputString(value, new Source(source, name, value));
161+
}
162+
135163
@Override
136164
public void taint(final byte origin, @Nullable final Object... toTaintArray) {
137165
if (toTaintArray == null || toTaintArray.length == 0) {
@@ -171,7 +199,7 @@ public void taint(final byte origin, @Nullable final Collection<Object> toTaintC
171199

172200
@Override
173201
public void taint(
174-
@Nullable Taintable t, byte origin, @Nullable String name, @Nullable String value) {
202+
byte origin, @Nullable String name, @Nullable String value, @Nullable Taintable t) {
175203
if (t == null) {
176204
return;
177205
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/source/WebModuleImpl.java

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import java.util.Collection;
1111
import java.util.Iterator;
1212
import java.util.Map;
13-
import javax.annotation.Nonnull;
1413
import javax.annotation.Nullable;
1514

1615
public class WebModuleImpl implements WebModule {
@@ -20,18 +19,6 @@ public void onParameterNames(@Nullable final Collection<String> paramNames) {
2019
onNamed(paramNames, SourceTypes.REQUEST_PARAMETER_NAME);
2120
}
2221

23-
@Override
24-
public void onParameterValue(
25-
@Nullable final String paramName, @Nullable final String paramValue) {
26-
onNamed(paramName, paramValue, SourceTypes.REQUEST_PARAMETER_VALUE);
27-
}
28-
29-
@Override
30-
public void onPathParameterValue(
31-
@Nullable final String paramName, @Nullable final String paramValue) {
32-
onNamed(paramName, paramValue, SourceTypes.REQUEST_PATH_PARAMETER);
33-
}
34-
3522
@Override
3623
public void onParameterValues(
3724
@Nullable final String paramName, @Nullable final String[] paramValues) {
@@ -54,11 +41,6 @@ public void onHeaderNames(@Nullable final Collection<String> headerNames) {
5441
onNamed(headerNames, SourceTypes.REQUEST_HEADER_NAME);
5542
}
5643

57-
@Override
58-
public void onHeaderValue(@Nullable final String headerName, @Nullable final String headerValue) {
59-
onNamed(headerName, headerValue, SourceTypes.REQUEST_HEADER_VALUE);
60-
}
61-
6244
@Override
6345
public void onHeaderValues(
6446
@Nullable final String headerName, @Nullable final Collection<String> headerValues) {
@@ -70,38 +52,6 @@ public void onCookieNames(@Nullable Iterable<String> cookieNames) {
7052
onNamed(cookieNames, SourceTypes.REQUEST_COOKIE_NAME);
7153
}
7254

73-
@Override
74-
public void onCookieValue(@Nullable final String cookieName, @Nullable final String cookieValue) {
75-
onNamed(cookieName, cookieValue, SourceTypes.REQUEST_COOKIE_VALUE);
76-
}
77-
78-
@Override
79-
public void onQueryString(@Nullable final String queryString) {
80-
if (!canBeTainted(queryString)) {
81-
return;
82-
}
83-
final IastRequestContext ctx = IastRequestContext.get();
84-
if (ctx == null) {
85-
return;
86-
}
87-
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
88-
taintedObjects.taintInputString(
89-
queryString, new Source(SourceTypes.REQUEST_QUERY, null, queryString));
90-
}
91-
92-
private static void onNamed(
93-
@Nullable final String name, @Nullable final String value, final byte source) {
94-
if (!canBeTainted(value)) {
95-
return;
96-
}
97-
final IastRequestContext ctx = IastRequestContext.get();
98-
if (ctx == null) {
99-
return;
100-
}
101-
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
102-
taintedObjects.taintInputString(value, new Source(source, name, value));
103-
}
104-
10555
private static void onNamed(@Nullable final Iterable<String> names, final byte source) {
10656
if (names == null) {
10757
return;
@@ -186,34 +136,4 @@ private static void onNamed(@Nullable final Map<String, String[]> values, final
186136
}
187137
}
188138
}
189-
190-
@Override
191-
public void onRequestPathParameter(
192-
@Nullable String paramName, @Nullable String value, @Nonnull Object ctx_) {
193-
if (ctx_ == null || !canBeTainted(value)) {
194-
return;
195-
}
196-
final IastRequestContext ctx = (IastRequestContext) ctx_;
197-
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
198-
taintedObjects.taintInputString(
199-
value, new Source(SourceTypes.REQUEST_PATH_PARAMETER, paramName, value));
200-
}
201-
202-
@Override
203-
public void onRequestMatrixParameter(
204-
@Nonnull String paramName, @Nullable String value, @Nonnull Object ctx_) {
205-
if (ctx_ == null || paramName == null || !canBeTainted(value)) {
206-
return;
207-
}
208-
final IastRequestContext ctx = (IastRequestContext) ctx_;
209-
final TaintedObjects taintedObjects = ctx.getTaintedObjects();
210-
taintedObjects.taintInputString(
211-
value, new Source(SourceTypes.REQUEST_MATRIX_PARAMETER, paramName, value));
212-
}
213-
214-
@Override
215-
public void onInjectedParameter(
216-
@Nullable String name, @Nullable String value, @Nonnull byte sourceType) {
217-
onNamed(name, value, sourceType);
218-
}
219139
}

dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/PropagationModuleTest.groovy

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class PropagationModuleTest extends IastModuleImplTestBase {
7070
'taintIfAnyInputIsTainted' | [null, null]
7171
'taintIfAnyInputIsTainted' | [null, [].toArray()]
7272
'taintIfAnyInputIsTainted' | ['test', [].toArray()]
73+
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, 'name', null as String]
74+
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, null as String, null as String]
75+
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, 'name', '']
7376
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, null as Object[]]
7477
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, [] as Object[]]
7578
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, null as Collection]
@@ -93,11 +96,12 @@ class PropagationModuleTest extends IastModuleImplTestBase {
9396
'taintIfInputIsTainted' | [SourceTypes.REQUEST_PARAMETER_VALUE, ['value'].toSet(), new Object()]
9497
'taintIfInputIsTainted' | [SourceTypes.REQUEST_PARAMETER_VALUE, [key: 'value'].entrySet().toList(), new Object()]
9598
'taintIfAnyInputIsTainted' | ['value', ['test', 'test2'].toArray()]
99+
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value']
96100
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, [new Object()] as Object[]]
97101
'taint' | [SourceTypes.REQUEST_PARAMETER_VALUE, [new Object()]]
98102
}
99103

100-
void 'test #method'() {
104+
void 'test propagation for #method'() {
101105
given:
102106
final toTaint = toTaintClosure.call(args)
103107
final targetMethod = module.&"$method"
@@ -145,6 +149,63 @@ class PropagationModuleTest extends IastModuleImplTestBase {
145149
'taintIfAnyInputIsTainted' | ['Hello', [new MockTaintable()].toArray()] | { it[0] } | { it[1][0] }
146150
}
147151

152+
void 'test value source for #method'() {
153+
given:
154+
final span = Mock(AgentSpan)
155+
tracer.activeSpan() >> span
156+
final reqCtx = Mock(RequestContext)
157+
span.getRequestContext() >> reqCtx
158+
final ctx = new IastRequestContext()
159+
reqCtx.getData(RequestContextSlot.IAST) >> ctx
160+
161+
when:
162+
module."$method"(source, name, value)
163+
164+
then:
165+
1 * tracer.activeSpan() >> span
166+
1 * span.getRequestContext() >> reqCtx
167+
1 * reqCtx.getData(RequestContextSlot.IAST) >> ctx
168+
0 * _
169+
ctx.getTaintedObjects().get(name) == null
170+
def to = ctx.getTaintedObjects().get(value)
171+
to != null
172+
to.get() == value
173+
to.ranges.size() == 1
174+
to.ranges[0].start == 0
175+
to.ranges[0].length == value.length()
176+
to.ranges[0].source == new Source(source, name, value)
177+
178+
where:
179+
method | name | value | source
180+
'taint' | null | 'value' | SourceTypes.REQUEST_PARAMETER_VALUE
181+
'taint' | 'name' | 'value' | SourceTypes.REQUEST_PARAMETER_VALUE
182+
}
183+
184+
void 'taint with context for #method'() {
185+
setup:
186+
def ctx = new IastRequestContext()
187+
188+
when:
189+
module."$method"(ctx as Object, source, name, value)
190+
191+
then:
192+
ctx.getTaintedObjects().get(name) == null
193+
def to = ctx.getTaintedObjects().get(value)
194+
to != null
195+
to.get() == value
196+
to.ranges.size() == 1
197+
to.ranges[0].start == 0
198+
to.ranges[0].length == value.length()
199+
to.ranges[0].source == new Source(source, name, value)
200+
0 * _
201+
202+
where:
203+
method | name | value | source
204+
'taint' | null | "value" | SourceTypes.REQUEST_PATH_PARAMETER
205+
'taint' | "" | "value" | SourceTypes.REQUEST_PATH_PARAMETER
206+
'taint' | "param" | "value" | SourceTypes.REQUEST_PATH_PARAMETER
207+
}
208+
148209
void 'test taint'() {
149210
given:
150211
final method = module.&taint

0 commit comments

Comments
 (0)