diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/iast/NamedContext.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/iast/NamedContext.java index 9132b703bf3..5a202a73ea8 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/iast/NamedContext.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/iast/NamedContext.java @@ -2,8 +2,9 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; -import datadog.trace.api.iast.Taintable.Source; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.ContextStore; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nonnull; @@ -30,7 +31,8 @@ public static NamedContext getOrCreate( } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final Source source = module.findSource(target); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + final Source source = module.findSource(to, target); if (source != null) { result = new NamedContextImpl(module, source); } @@ -60,7 +62,7 @@ private static class NamedContextImpl extends NamedContext { @Nullable private String currentName; private boolean fetched; - @Nullable private IastContext context; + @Nullable private TaintedObjects to; public NamedContextImpl(@Nonnull final PropagationModule module, @Nonnull final Source source) { this.module = module; @@ -69,7 +71,7 @@ public NamedContextImpl(@Nonnull final PropagationModule module, @Nonnull final @Override public void taintValue(@Nullable final String value) { - module.taintString(iastCtx(), value, source.getOrigin(), currentName, source.getValue()); + module.taintObject(to(), value, source.getOrigin(), currentName, source.getValue()); } @Override @@ -79,7 +81,7 @@ public void taintName(@Nullable final String name) { // prevent tainting the same name more than once if (currentName != name) { currentName = name; - module.taintString(iastCtx(), name, source.getOrigin(), name, source.getValue()); + module.taintObject(to(), name, source.getOrigin(), name, source.getValue()); } } @@ -88,12 +90,12 @@ public void setCurrentName(@Nullable final String name) { currentName = name; } - private IastContext iastCtx() { + private TaintedObjects to() { if (!fetched) { fetched = true; - context = IastContext.Provider.get(); + to = IastContext.Provider.taintedObjects(); } - return context; + return to; } } } diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/iast/NamedContextTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/iast/NamedContextTest.groovy index 6ef33c9d91e..958cbdf3886 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/iast/NamedContextTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/iast/NamedContextTest.groovy @@ -3,8 +3,8 @@ package datadog.trace.bootstrap.instrumentation.iast import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable.Source import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import datadog.trace.bootstrap.ContextStore import datadog.trace.test.util.DDSpecification @@ -31,14 +31,14 @@ class NamedContextTest extends DDSpecification { then: 1 * store.get(target) >> null - 1 * module.findSource(target) >> source + 1 * module.findSource(_, target) >> source 1 * store.put(target, _) when: context.taintName(name) then: - 1 * module.taintString(_, name, source.origin, name, source.value) + 1 * module.taintObject(_, name, source.origin, name, source.value) when: context.taintName(name) @@ -50,7 +50,7 @@ class NamedContextTest extends DDSpecification { context.taintValue(value) then: - 1 * module.taintString(_, value, source.origin, name, source.value) + 1 * module.taintObject(_, value, source.origin, name, source.value) 0 * _ } @@ -62,7 +62,7 @@ class NamedContextTest extends DDSpecification { final ctx = NamedContext.getOrCreate(store, target) then: - 1 * module.findSource(target) >> null + 1 * module.findSource(_, target) >> null 1 * store.put(target, _) when: @@ -82,5 +82,20 @@ class NamedContextTest extends DDSpecification { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/AbstractBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/AbstractBenchmark.java index 6b36b1079c7..083dba05353 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/AbstractBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/AbstractBenchmark.java @@ -3,14 +3,15 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; import com.datadog.iast.IastSystem; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; -import com.datadog.iast.taint.TaintedObjects; +import com.datadog.iast.model.SourceImpl; import datadog.trace.api.Config; import datadog.trace.api.ProductActivation; import datadog.trace.api.gateway.InstrumentationGateway; import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; @@ -95,7 +96,7 @@ protected E notTainted(final E value) { } protected Source source() { - return new Source((byte) 0, "key", "value"); + return new SourceImpl((byte) 0, "key", "value"); } private static long computeHash(final Object value) { diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderAppendBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderAppendBenchmark.java index 53e4e44a8af..ceaf38aed5b 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderAppendBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderAppendBenchmark.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.instrumentation.java.lang.StringBuilderCallSite; import org.openjdk.jmh.annotations.Benchmark; @@ -17,14 +17,14 @@ protected Context initializeContext() { final IastRequestContext context = new IastRequestContext(); final String notTainted = notTainted("I am not a tainted string"); final String tainted = - tainted(context, "I am a tainted string", new Range(5, 6, source(), NOT_MARKED)); + tainted(context, "I am a tainted string", new RangeImpl(5, 6, source(), NOT_MARKED)); final StringBuilder notTaintedBuilder = notTainted(new StringBuilder("I am not a tainted string builder")); final StringBuilder taintedBuilder = tainted( context, new StringBuilder("I am a tainted string builder"), - new Range(5, 6, source(), NOT_MARKED)); + new RangeImpl(5, 6, source(), NOT_MARKED)); return new Context(context, notTainted, tainted, notTaintedBuilder, taintedBuilder); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderBatchBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderBatchBenchmark.java index dcc0aad5edb..d2bd57cf0de 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderBatchBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderBatchBenchmark.java @@ -4,7 +4,7 @@ import static java.util.concurrent.TimeUnit.MICROSECONDS; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.instrumentation.java.lang.StringBuilderCallSite; import java.util.ArrayList; @@ -36,7 +36,8 @@ protected StringBuilderBatchBenchmark.Context initializeContext() { final String value; if (current < limit) { value = - tainted(context, UUID.randomUUID().toString(), new Range(3, 6, source(), NOT_MARKED)); + tainted( + context, UUID.randomUUID().toString(), new RangeImpl(3, 6, source(), NOT_MARKED)); } else { value = notTainted(UUID.randomUUID().toString()); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderInitBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderInitBenchmark.java index e6a402585ee..8f3dd781e9d 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderInitBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderInitBenchmark.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.instrumentation.java.lang.StringBuilderCallSite; import org.openjdk.jmh.annotations.Benchmark; @@ -17,7 +17,7 @@ protected Context initializeContext() { final IastRequestContext context = new IastRequestContext(); final String notTainted = notTainted("I am not a tainted string"); final String tainted = - tainted(context, "I am a tainted string", new Range(3, 6, source(), NOT_MARKED)); + tainted(context, "I am a tainted string", new RangeImpl(3, 6, source(), NOT_MARKED)); return new Context(context, notTainted, tainted); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderToStringBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderToStringBenchmark.java index 4175dce68af..24d1c316b5e 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderToStringBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringBuilderToStringBenchmark.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.instrumentation.java.lang.StringBuilderCallSite; import org.openjdk.jmh.annotations.Benchmark; @@ -21,7 +21,7 @@ protected Context initializeContext() { tainted( context, new StringBuilder("I am a tainted string builder"), - new Range(5, 7, source(), NOT_MARKED)); + new RangeImpl(5, 7, source(), NOT_MARKED)); return new Context(context, notTaintedBuilder, taintedBuilder); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatBenchmark.java index 2dfbb8fff29..ed5e567e842 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatBenchmark.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.instrumentation.java.lang.StringCallSite; import org.openjdk.jmh.annotations.Benchmark; @@ -16,7 +16,7 @@ protected StringConcatBenchmark.Context initializeContext() { final IastRequestContext context = new IastRequestContext(); final String notTainted = notTainted("I am not a tainted string"); final String tainted = - tainted(context, "I am a tainted string", new Range(3, 5, source(), NOT_MARKED)); + tainted(context, "I am a tainted string", new RangeImpl(3, 5, source(), NOT_MARKED)); return new StringConcatBenchmark.Context(context, notTainted, tainted); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBatchBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBatchBenchmark.java index 2a994683b0b..d9163a7c971 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBatchBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBatchBenchmark.java @@ -4,7 +4,7 @@ import static java.util.concurrent.TimeUnit.MICROSECONDS; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import java.lang.invoke.MethodHandle; @@ -56,7 +56,7 @@ protected StringConcatFactoryBatchBenchmark.Context initializeContext() { double current = i / (double) stringCount; final String value; if (current < limit) { - value = tainted(context, "Yep, tainted", new Range(3, 5, source(), NOT_MARKED)); + value = tainted(context, "Yep, tainted", new RangeImpl(3, 5, source(), NOT_MARKED)); } else { value = notTainted("Nop, tainted"); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBenchmark.java index 0342d1ab377..d4d2e7ac13f 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringConcatFactoryBenchmark.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; +import com.datadog.iast.model.RangeImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import org.openjdk.jmh.annotations.Benchmark; @@ -16,7 +16,8 @@ public class StringConcatFactoryBenchmark protected StringConcatFactoryBenchmark.Context initializeContext() { final IastContext context = new IastRequestContext(); final String notTainted = notTainted("Nop, tainted"); - final String tainted = tainted(context, "Yep, tainted", new Range(3, 5, source(), NOT_MARKED)); + final String tainted = + tainted(context, "Yep, tainted", new RangeImpl(3, 5, source(), NOT_MARKED)); return new StringConcatFactoryBenchmark.Context(context, notTainted, tainted); } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringJoinBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringJoinBenchmark.java index 010815d7dcc..5208cf9fedc 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringJoinBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringJoinBenchmark.java @@ -3,10 +3,11 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; +import com.datadog.iast.model.RangeImpl; +import com.datadog.iast.model.SourceImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; +import datadog.trace.api.iast.taint.Range; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Fork; @@ -23,7 +24,8 @@ protected StringJoinBenchmark.Context initializeContext() { .taint( tainted, new Range[] { - new Range(0, tainted.length(), new Source((byte) 0, "key", "value"), NOT_MARKED) + new RangeImpl( + 0, tainted.length(), new SourceImpl((byte) 0, "key", "value"), NOT_MARKED) }); final String taintedDelimiter = new String("-"); @@ -32,8 +34,11 @@ protected StringJoinBenchmark.Context initializeContext() { .taint( taintedDelimiter, new Range[] { - new Range( - 0, taintedDelimiter.length(), new Source((byte) 1, "key", "value"), NOT_MARKED) + new RangeImpl( + 0, + taintedDelimiter.length(), + new SourceImpl((byte) 1, "key", "value"), + NOT_MARKED) }); return new StringJoinBenchmark.Context( diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringSubsequenceBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringSubsequenceBenchmark.java index d6e7b7cbb4e..acddc7e38ae 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringSubsequenceBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/propagation/StringSubsequenceBenchmark.java @@ -3,10 +3,11 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import com.datadog.iast.IastRequestContext; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; +import com.datadog.iast.model.RangeImpl; +import com.datadog.iast.model.SourceImpl; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; +import datadog.trace.api.iast.taint.Range; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Fork; @@ -29,7 +30,7 @@ protected StringSubsequenceBenchmark.Context initializeContext() { .taint( taintedLoseRange, new Range[] { - new Range(0, RANGE_SIZE, new Source((byte) 0, "key", "value"), NOT_MARKED) + new RangeImpl(0, RANGE_SIZE, new SourceImpl((byte) 0, "key", "value"), NOT_MARKED) }); final String taintedModifyRange = new String(DEFAULT_STRING); @@ -38,7 +39,7 @@ protected StringSubsequenceBenchmark.Context initializeContext() { .taint( taintedModifyRange, new Range[] { - new Range(1, RANGE_SIZE, new Source((byte) 1, "key", "value"), NOT_MARKED) + new RangeImpl(1, RANGE_SIZE, new SourceImpl((byte) 1, "key", "value"), NOT_MARKED) }); return new StringSubsequenceBenchmark.Context( diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapGetsBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapGetsBenchmark.java index 96416278c83..142c55838de 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapGetsBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapGetsBenchmark.java @@ -3,7 +3,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import com.datadog.iast.model.Range; +import datadog.trace.api.iast.taint.Range; import java.util.ArrayList; import java.util.List; import org.openjdk.jmh.annotations.Benchmark; @@ -45,12 +45,12 @@ public void setup(BenchmarkParams params) { for (int i = 0; i < INITIAL_OP_COUNT; i++) { final Object k = new Object(); initialObjectList.add(k); - map.put(new TaintedObject(k, new Range[0])); + map.put(new TaintedObjectEntry(k, new Range[0])); } for (int i = 0; i < OP_COUNT; i++) { final Object k = new Object(); objectList.add(k); - map.put(new TaintedObject(k, new Range[0])); + map.put(new TaintedObjectEntry(k, new Range[0])); } } diff --git a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapPutsBenchmark.java b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapPutsBenchmark.java index 90b92140874..087e49c85d5 100644 --- a/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapPutsBenchmark.java +++ b/dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapPutsBenchmark.java @@ -3,7 +3,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import com.datadog.iast.model.Range; +import datadog.trace.api.iast.taint.Range; import datadog.trace.test.util.CircularBuffer; import java.util.ArrayList; import java.util.IdentityHashMap; @@ -51,7 +51,7 @@ public void setup(BenchmarkParams params) { for (int i = 0; i < INITIAL_OP_COUNT; i++) { final Object k = new Object(); initialObjectList.add(k); - map.put(new TaintedObject(k, EMPTY_RANGES)); + map.put(new TaintedObjectEntry(k, EMPTY_RANGES)); } } @@ -60,7 +60,7 @@ public void setup(BenchmarkParams params) { public void baseline() { for (int i = 0; i < OP_COUNT; i++) { final Object k = new Object(); - final TaintedObject to = new TaintedObject(k, EMPTY_RANGES); + final TaintedObjectEntry to = new TaintedObjectEntry(k, EMPTY_RANGES); gcHandler.add(to); map.put(to); } @@ -71,7 +71,7 @@ public void baseline() { public void puts() { for (int i = 0; i < OP_COUNT; i++) { final Object k = new Object(); - final TaintedObject to = new TaintedObject(k, EMPTY_RANGES); + final TaintedObjectEntry to = new TaintedObjectEntry(k, EMPTY_RANGES); gcHandler.add(to); map.put(to); } @@ -83,7 +83,7 @@ public void puts() { */ private static class GarbageCollectorHandler { - private final Map map; + private final Map map; private final CircularBuffer alive; public GarbageCollectorHandler(final int aliveCount) { @@ -91,14 +91,14 @@ public GarbageCollectorHandler(final int aliveCount) { alive = new CircularBuffer<>(aliveCount); } - public void add(TaintedObject reference) { + public void add(TaintedObjectEntry reference) { if (reference == null || reference.get() == null) { return; } final Object referent = reference.get(); final Object toRemove = alive.add(referent); if (toRemove != null) { - final TaintedObject taintedObject = map.remove(toRemove); + final TaintedObjectEntry taintedObject = map.remove(toRemove); taintedObject.enqueue(); } map.put(reference.get(), reference); diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/GrpcRequestMessageHandler.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/GrpcRequestMessageHandler.java index cfad9aa9847..1cf2e6ef610 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/GrpcRequestMessageHandler.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/GrpcRequestMessageHandler.java @@ -7,6 +7,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.telemetry.IastMetric; import datadog.trace.api.iast.telemetry.IastMetricCollector; import java.util.Map; @@ -34,10 +35,10 @@ public Flow apply(final RequestContext ctx, final Object o) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null && o != null) { final IastContext iastCtx = ctx.getData(RequestContextSlot.IAST); + final TaintedObjects to = iastCtx.getTaintedObjects(); final byte source = SourceTypes.GRPC_BODY; final int tainted = - module.taintObjectDeeply( - iastCtx, o, source, GrpcRequestMessageHandler::visitProtobufArtifact); + module.taintObjectDeeply(to, o, source, GrpcRequestMessageHandler::visitProtobufArtifact); if (tainted > 0) { IastMetricCollector.add(IastMetric.EXECUTED_SOURCE, source, tainted, iastCtx); } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContext.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContext.java deleted file mode 100644 index 44be00c59be..00000000000 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContext.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.datadog.iast; - -import com.datadog.iast.taint.TaintedMap; -import com.datadog.iast.taint.TaintedObjects; -import datadog.trace.api.iast.IastContext; -import java.io.IOException; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class IastGlobalContext implements IastContext { - - private final TaintedObjects taintedObjects; - - public IastGlobalContext(final TaintedObjects taintedObjects) { - this.taintedObjects = taintedObjects; - } - - @SuppressWarnings("unchecked") - @Nonnull - @Override - public TaintedObjects getTaintedObjects() { - return taintedObjects; - } - - @Override - public void close() throws IOException {} - - public static class Provider extends IastContext.Provider { - - // (16384 * 4) buckets: approx 256K - static final int MAP_SIZE = TaintedMap.DEFAULT_CAPACITY * (1 << 2); - static final int MAX_AGE = TaintedMap.DEFAULT_MAX_AGE; - static final TimeUnit MAX_AGE_UNIT = TaintedMap.DEFAULT_MAX_AGE_UNIT; - - // Map that with purge option - final IastContext globalContext = - new IastGlobalContext( - TaintedObjects.build(TaintedMap.buildWithPurge(MAP_SIZE, MAX_AGE, MAX_AGE_UNIT))); - - @Nullable - @Override - public IastContext resolve() { - return globalContext; - } - - @Override - public IastContext buildRequestContext() { - return new IastRequestContext(globalContext.getTaintedObjects()); - } - - @Override - public void releaseRequestContext(@Nonnull final IastContext context) { - // nothing to release in global mode - } - } -} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContextProvider.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContextProvider.java new file mode 100644 index 00000000000..24ceb9fefcb --- /dev/null +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastGlobalContextProvider.java @@ -0,0 +1,37 @@ +package com.datadog.iast; + +import com.datadog.iast.taint.TaintedMap; +import com.datadog.iast.taint.TaintedObjectsMap; +import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.TaintedObjects; +import java.util.concurrent.TimeUnit; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class IastGlobalContextProvider extends IastContext.Provider { + + // (16384 * 4) buckets: approx 256K + static final int MAP_SIZE = TaintedMap.DEFAULT_CAPACITY * (1 << 2); + static final int MAX_AGE = TaintedMap.DEFAULT_MAX_AGE; + static final TimeUnit MAX_AGE_UNIT = TaintedMap.DEFAULT_MAX_AGE_UNIT; + + // Map that with purge option + final TaintedObjects taintedObjects = + TaintedObjectsMap.build(TaintedMap.buildWithPurge(MAP_SIZE, MAX_AGE, MAX_AGE_UNIT)); + + @Nullable + @Override + public TaintedObjects resolveTaintedObjects() { + return taintedObjects; + } + + @Override + public IastContext buildRequestContext() { + return new IastRequestContext(taintedObjects); + } + + @Override + public void releaseRequestContext(@Nonnull final IastContext context) { + // nothing to release in global mode + } +} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContext.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContext.java deleted file mode 100644 index ad91165da20..00000000000 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContext.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.datadog.iast; - -import com.datadog.iast.taint.TaintedObjects; -import datadog.trace.api.iast.IastContext; -import java.io.IOException; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -public class IastOptOutContext implements IastContext { - - @Nonnull - @SuppressWarnings("unchecked") - @NotNull - @Override - public TaintedObjects getTaintedObjects() { - return TaintedObjects.NoOp.INSTANCE; - } - - @Override - public void close() throws IOException {} - - public static class Provider extends IastContext.Provider { - - final IastContext optOutContext = new IastOptOutContext(); - - @Nullable - @Override - public IastContext resolve() { - return optOutContext; - } - - @Override - public IastContext buildRequestContext() { - return new IastRequestContext(optOutContext.getTaintedObjects()); - } - - @Override - public void releaseRequestContext(@Nonnull final IastContext context) { - // nothing to release in opt out mode - } - } -} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContextProvider.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContextProvider.java new file mode 100644 index 00000000000..15793aa17cb --- /dev/null +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastOptOutContextProvider.java @@ -0,0 +1,25 @@ +package com.datadog.iast; + +import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.TaintedObjects; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class IastOptOutContextProvider extends IastContext.Provider { + + @Nullable + @Override + public TaintedObjects resolveTaintedObjects() { + return TaintedObjects.NoOp.INSTANCE; + } + + @Override + public IastContext buildRequestContext() { + return new IastRequestContext(TaintedObjects.NoOp.INSTANCE); + } + + @Override + public void releaseRequestContext(@Nonnull final IastContext context) { + // nothing to release in opt out mode + } +} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java index d237935ac01..34945394692 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java @@ -5,16 +5,13 @@ import com.datadog.iast.model.VulnerabilityBatch; import com.datadog.iast.overhead.OverheadContext; import com.datadog.iast.taint.TaintedMap; -import com.datadog.iast.taint.TaintedObjects; +import com.datadog.iast.taint.TaintedObjectsMap; import com.datadog.iast.util.Wrapper; import datadog.trace.api.Config; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.telemetry.IastMetricCollector; import datadog.trace.api.iast.telemetry.IastMetricCollector.HasMetricCollector; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.io.IOException; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; @@ -44,7 +41,7 @@ public class IastRequestContext implements IastContext, HasMetricCollector { @Deprecated public IastRequestContext() { // map without purge (it will be cleared on request end) - this(TaintedObjects.build(TaintedMap.build(MAP_SIZE))); + this(TaintedObjectsMap.build(TaintedMap.build(MAP_SIZE))); } public IastRequestContext(final TaintedObjects taintedObjects) { @@ -106,7 +103,6 @@ public OverheadContext getOverheadContext() { return overheadContext; } - @SuppressWarnings("unchecked") @Nonnull @Override public TaintedObjects getTaintedObjects() { @@ -147,23 +143,16 @@ public static class Provider extends IastContext.Provider { @Nullable @Override - public IastContext resolve() { - final AgentSpan span = AgentTracer.activeSpan(); - if (span == null) { - return null; - } - final RequestContext ctx = span.getRequestContext(); - if (ctx == null) { - return null; - } - return ctx.getData(RequestContextSlot.IAST); + public TaintedObjects resolveTaintedObjects() { + final IastContext ctx = get(); + return ctx == null ? null : ctx.getTaintedObjects(); } @Override public IastContext buildRequestContext() { TaintedObjects taintedObjects = pool.poll(); if (taintedObjects == null) { - taintedObjects = TaintedObjects.build(TaintedMap.build(MAP_SIZE)); + taintedObjects = TaintedObjectsMap.build(TaintedMap.build(MAP_SIZE)); } final IastRequestContext ctx = new IastRequestContext(taintedObjects); ctx.release = this::releaseRequestContext; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java index 806fb36b2e8..07e6d9218f7 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java @@ -112,9 +112,9 @@ public static void start( private static IastContext.Provider contextProvider( final ProductActivation iast, final boolean global) { if (iast != FULLY_ENABLED) { - return new IastOptOutContext.Provider(); + return new IastOptOutContextProvider(); } else { - return global ? new IastGlobalContext.Provider() : new IastRequestContext.Provider(); + return global ? new IastGlobalContextProvider() : new IastRequestContext.Provider(); } } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/Reporter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/Reporter.java index 01f7d991b80..fe324e0e1da 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/Reporter.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/Reporter.java @@ -6,7 +6,7 @@ import com.datadog.iast.model.Vulnerability; import com.datadog.iast.model.VulnerabilityBatch; -import com.datadog.iast.taint.TaintedObjects; +import com.datadog.iast.taint.TaintedObjectsMap; import datadog.trace.api.Config; import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; @@ -137,7 +137,7 @@ private VulnerabilityBatch getOrCreateVulnerabilityBatch(final AgentSpan span) { private AgentSpan startNewSpan() { final AgentSpan.Context tagContext = new TagContext() - .withRequestContextDataIast(new IastRequestContext(TaintedObjects.NoOp.INSTANCE)); + .withRequestContextDataIast(new IastRequestContext(TaintedObjectsMap.NoOp.INSTANCE)); final AgentSpan span = tracer() .startSpan("iast", VULNERABILITY_SPAN_NAME, tagContext) diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Evidence.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Evidence.java index ab6d91ecbb4..77cc31f5cbf 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Evidence.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Evidence.java @@ -1,5 +1,6 @@ package com.datadog.iast.model; +import datadog.trace.api.iast.taint.Range; import java.util.Arrays; import java.util.HashMap; import java.util.Map; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Range.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/RangeImpl.java similarity index 61% rename from dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Range.java rename to dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/RangeImpl.java index 25b0dbab667..c0a8f9494f6 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Range.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/RangeImpl.java @@ -2,24 +2,23 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; -import com.datadog.iast.model.json.SourceIndex; -import com.datadog.iast.util.Ranged; -import java.util.HashSet; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.util.Ranged; import java.util.Objects; -import java.util.Set; import java.util.StringJoiner; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; -import javax.annotation.Nullable; -public final class Range implements Ranged { +public final class RangeImpl implements Ranged, Range { private final @Nonnegative int start; private final @Nonnegative int length; - private final @Nonnull @SourceIndex Source source; + private final @Nonnull Source source; private final int marks; - public Range(final int start, final int length, @Nonnull final Source source, final int marks) { + public RangeImpl( + final int start, final int length, @Nonnull final Source source, final int marks) { this.start = start; this.length = length; this.source = source; @@ -54,7 +53,9 @@ public boolean equals(Object o) { return false; } Range range = (Range) o; - return start == range.start && length == range.length && Objects.equals(source, range.source); + return start == range.getStart() + && length == range.getLength() + && Objects.equals(source, range.getSource()); } @Override @@ -79,9 +80,10 @@ public Range shift(final int offset) { if (offset == 0) { return this; } - return new Range(start + offset, length, source, marks); + return new RangeImpl(start + offset, length, source, marks); } + @Override public boolean isMarked(final int mark) { return (marks & mark) != NOT_MARKED; } @@ -91,20 +93,10 @@ public Range consolidate() { if (!source.isReference()) { return this; } - return new Range( - start, length, new Source(source.getOrigin(), source.getName(), source.getValue()), marks); - } - - public @Nullable Set getMarkedVulnerabilities() { - if (marks == NOT_MARKED) { - return null; - } - Set vulnerabilities = new HashSet<>(); - for (VulnerabilityType type : VulnerabilityType.MARKED_VULNERABILITIES) { - if ((marks & type.mark()) != 0) { - vulnerabilities.add(type); - } - } - return vulnerabilities; + return new RangeImpl( + start, + length, + new SourceImpl(source.getOrigin(), source.getName(), source.getValue()), + marks); } } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Source.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/SourceImpl.java similarity index 87% rename from dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Source.java rename to dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/SourceImpl.java index 854c38b9234..02d06113b4a 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Source.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/SourceImpl.java @@ -2,9 +2,8 @@ import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY; -import com.datadog.iast.model.json.SourceTypeString; import datadog.trace.api.iast.SourceTypes; -import datadog.trace.api.iast.Taintable; +import datadog.trace.api.iast.taint.Source; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.lang.ref.Reference; import java.util.Objects; @@ -13,9 +12,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class Source implements Taintable.Source { +public final class SourceImpl implements Source { - private static final Logger LOGGER = LoggerFactory.getLogger(Source.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SourceImpl.class); /** Placeholder for non char sequence objects */ public static final Object PROPAGATION_PLACEHOLDER = new Object(); @@ -24,12 +23,12 @@ public final class Source implements Taintable.Source { public static final String GARBAGE_COLLECTED_REF = "[unknown: original value was garbage collected]"; - private final @SourceTypeString byte origin; + private final byte origin; @Nullable private final Object name; @Nullable private final Object value; private boolean gcReported; - public Source(final byte origin, @Nullable final Object name, @Nullable final Object value) { + public SourceImpl(final byte origin, @Nullable final Object name, @Nullable final Object value) { this.origin = origin; this.name = name; this.value = value; @@ -94,7 +93,7 @@ private String asString(@Nullable final Object target) { @Override public String toString() { - return new StringJoiner(", ", Source.class.getSimpleName() + "[", "]") + return new StringJoiner(", ", SourceImpl.class.getSimpleName() + "[", "]") .add("origin=" + SourceTypes.toString(origin)) .add("name='" + getName() + "'") .add("value='" + getValue() + "'") @@ -106,7 +105,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Source source = (Source) o; - return origin == source.origin + return origin == source.getOrigin() && Objects.equals(getName(), source.getName()) && Objects.equals(getValue(), source.getValue()); } @@ -120,9 +119,10 @@ public Source attachValue(final Object newValue) { if (value != PROPAGATION_PLACEHOLDER) { return this; } - return new Source(origin, name, newValue); + return new SourceImpl(origin, name, newValue); } + @Override public boolean isReference() { return name instanceof Reference || value instanceof Reference; } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/AdapterFactory.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/AdapterFactory.java index 30bfca64bc5..029e0ff6f3c 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/AdapterFactory.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/AdapterFactory.java @@ -1,7 +1,6 @@ package com.datadog.iast.model.json; import com.datadog.iast.model.Evidence; -import com.datadog.iast.model.Source; import com.datadog.iast.model.Vulnerability; import com.datadog.iast.model.VulnerabilityBatch; import com.datadog.iast.model.VulnerabilityType; @@ -10,6 +9,7 @@ import com.squareup.moshi.JsonWriter; import com.squareup.moshi.Moshi; import com.squareup.moshi.Types; +import datadog.trace.api.iast.taint.Source; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -69,18 +69,14 @@ public JsonAdapter create( @Nonnull final Set annotations, @Nonnull final Moshi moshi) { final Class rawType = Types.getRawType(type); - if (Source.class.equals(rawType)) { - if (hasSourceIndexAnnotation(annotations)) { - return new SourceIndexAdapter(); - } else { - return new SourceAdapter(); - } + if (Source.class.isAssignableFrom(rawType)) { + return new SourceAdapter(); } else if (VulnerabilityBatch.class.equals(rawType)) { return new VulnerabilityBatchAdapter(moshi); } else if (Vulnerability.class.equals(rawType)) { return new VulnerabilityAdapter(this, moshi); } else if (Evidence.class.equals(rawType)) { - return new EvidenceAdapter(moshi); + return new EvidenceAdapter(); } else if (VulnerabilityType.class.equals(rawType)) { return new VulnerabilityTypeAdapter(); } else if (TruncatedVulnerabilities.class.equals(rawType)) { @@ -89,15 +85,10 @@ public JsonAdapter create( return null; } - protected boolean hasSourceIndexAnnotation(@Nonnull final Set annotations) { - return annotations.stream() - .anyMatch(annotation -> annotation.annotationType() == SourceIndex.class); - } - public static class SourceIndexAdapter extends FormattingAdapter { @Override - public void toJson(@Nonnull final JsonWriter writer, @Nullable @SourceIndex final Source value) + public void toJson(@Nonnull final JsonWriter writer, @Nullable final Source value) throws IOException { if (value == null) { writer.nullValue(); diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/EvidenceAdapter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/EvidenceAdapter.java index 9aa13db2e56..fe547536b3f 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/EvidenceAdapter.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/EvidenceAdapter.java @@ -1,22 +1,23 @@ package com.datadog.iast.model.json; import static com.datadog.iast.model.json.TruncationUtils.writeTruncableValue; +import static com.datadog.iast.taint.Ranges.getMarkedVulnerabilities; import com.datadog.iast.model.Evidence; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; import com.datadog.iast.model.Vulnerability; import com.datadog.iast.model.VulnerabilityType; import com.datadog.iast.model.json.AdapterFactory.Context; import com.datadog.iast.model.json.AdapterFactory.RedactionContext; +import com.datadog.iast.model.json.AdapterFactory.SourceIndexAdapter; import com.datadog.iast.sensitive.SensitiveHandler; import com.datadog.iast.sensitive.SensitiveHandler.Tokenizer; -import com.datadog.iast.util.Ranged; import com.datadog.iast.util.RangedDeque; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; import datadog.trace.api.Config; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.util.Ranged; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -43,8 +44,8 @@ public class EvidenceAdapter extends FormattingAdapter { private final JsonAdapter defaultAdapter; private final JsonAdapter redactedAdapter; - public EvidenceAdapter(@Nonnull final Moshi moshi) { - sourceAdapter = moshi.adapter(Source.class, SourceIndex.class); + public EvidenceAdapter() { + sourceAdapter = new SourceIndexAdapter(); defaultAdapter = new DefaultEvidenceAdapter(); redactedAdapter = new RedactedEvidenceAdapter(); } @@ -143,7 +144,7 @@ private void writeValuePart( if (range != null) { writer.name("source"); sourceAdapter.toJson(writer, range.getSource()); - writeSecureMarks(writer, range.getMarkedVulnerabilities()); + writeSecureMarks(writer, getMarkedVulnerabilities(range)); } writer.endObject(); } @@ -422,7 +423,7 @@ private RedactableTaintedValuePart( .sorted(Comparator.comparing(Ranged::getStart)) .collect(Collectors.toList()); - this.markedTypes = range.getMarkedVulnerabilities(); + this.markedTypes = getMarkedVulnerabilities(range); } @Override diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceAdapter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceAdapter.java index 7f5ab7edc1f..1127759de44 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceAdapter.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceAdapter.java @@ -2,24 +2,23 @@ import static com.datadog.iast.model.json.TruncationUtils.writeTruncableValue; -import com.datadog.iast.model.Source; import com.datadog.iast.model.json.AdapterFactory.Context; import com.datadog.iast.model.json.AdapterFactory.RedactionContext; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonWriter; import datadog.trace.api.Config; +import datadog.trace.api.iast.SourceTypes; +import datadog.trace.api.iast.taint.Source; import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class SourceAdapter extends FormattingAdapter { - private final SourceTypeAdapter sourceTypeAdapter; private final JsonAdapter defaultAdapter; private final JsonAdapter redactedAdapter; public SourceAdapter() { - sourceTypeAdapter = new SourceTypeAdapter(); defaultAdapter = new DefaultSourceAdapter(); redactedAdapter = new RedactedSourceAdapter(); } @@ -44,7 +43,7 @@ private class DefaultSourceAdapter extends FormattingAdapter { public void toJson(@Nonnull JsonWriter writer, @Nonnull Source source) throws IOException { writer.beginObject(); writer.name("origin"); - sourceTypeAdapter.toJson(writer, source.getOrigin()); + writer.value(SourceTypes.toString(source.getOrigin())); writer.name("name"); writer.value(source.getName()); writer.name("value"); @@ -71,7 +70,7 @@ private void toRedactedJson( throws IOException { writer.beginObject(); writer.name("origin"); - sourceTypeAdapter.toJson(writer, source.getOrigin()); + writer.value(SourceTypes.toString(source.getOrigin())); writer.name("name"); writer.value(source.getName()); writer.name("redacted"); diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceIndex.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceIndex.java deleted file mode 100644 index bc6a8a26836..00000000000 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceIndex.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.datadog.iast.model.json; - -import com.squareup.moshi.JsonQualifier; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@JsonQualifier -public @interface SourceIndex {} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeAdapter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeAdapter.java deleted file mode 100644 index ca9b6a009ba..00000000000 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeAdapter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.datadog.iast.model.json; - -import com.squareup.moshi.FromJson; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.ToJson; -import datadog.trace.api.iast.SourceTypes; -import java.io.IOException; - -class SourceTypeAdapter { - - @ToJson - void toJson(JsonWriter writer, @SourceTypeString byte value) throws IOException { - final String stringValue = SourceTypes.toString(value); - if (stringValue == null) { - writer.nullValue(); - return; - } - writer.value(stringValue); - } - - @FromJson - @SourceTypeString - byte fromJson(JsonReader reader) { - throw new UnsupportedOperationException("SourceType deserialization not supported"); - } -} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeString.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeString.java deleted file mode 100644 index a0e47970882..00000000000 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/SourceTypeString.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.datadog.iast.model.json; - -import com.squareup.moshi.JsonQualifier; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@JsonQualifier -public @interface SourceTypeString {} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectAdapter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectAdapter.java index bee0d8ab221..c4d48e9e79b 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectAdapter.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectAdapter.java @@ -1,13 +1,13 @@ package com.datadog.iast.model.json; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; -import com.datadog.iast.taint.TaintedObject; import com.squareup.moshi.FromJson; import com.squareup.moshi.JsonReader; import com.squareup.moshi.JsonWriter; import com.squareup.moshi.ToJson; import datadog.trace.api.iast.SourceTypes; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObject; import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -21,9 +21,9 @@ public void toJson(@Nonnull final JsonWriter writer, @Nullable final TaintedObje writer.nullValue(); } else { writer.beginObject(); - final Object weak = value.get(); + final Object target = value.get(); writer.name("value"); - writer.value(weak == null ? "[Value GCed]" : weak.toString()); + writer.value(target == null ? "[Value GCed]" : target.toString()); writer.name("ranges"); writer.beginArray(); for (final Range range : value.getRanges()) { diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectEncoding.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectEncoding.java index 27a92bf7dd7..adc8d06c2f8 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectEncoding.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/TaintedObjectEncoding.java @@ -1,9 +1,9 @@ package com.datadog.iast.model.json; -import com.datadog.iast.taint.TaintedObject; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; import com.squareup.moshi.Types; +import datadog.trace.api.iast.taint.TaintedObject; import java.util.List; public class TaintedObjectEncoding { diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/VulnerabilityEncoding.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/VulnerabilityEncoding.java index 4838e4043f2..799a11caec5 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/VulnerabilityEncoding.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/json/VulnerabilityEncoding.java @@ -13,8 +13,7 @@ public class VulnerabilityEncoding { private static final Logger log = LoggerFactory.getLogger(VulnerabilityEncoding.class); private static final int MAX_SPAN_TAG_SIZE = 25000; - static final Moshi MOSHI = - new Moshi.Builder().add(new SourceTypeAdapter()).add(new AdapterFactory()).build(); + static final Moshi MOSHI = new Moshi.Builder().add(new AdapterFactory()).build(); private static final JsonAdapter BATCH_ADAPTER = MOSHI.adapter(VulnerabilityBatch.class); diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/CodecModuleImpl.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/CodecModuleImpl.java index 2bbe779babb..a03d07e32b9 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/CodecModuleImpl.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/CodecModuleImpl.java @@ -3,12 +3,12 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; import static datadog.trace.api.iast.VulnerabilityMarks.XSS_MARK; -import com.datadog.iast.taint.TaintedObject; -import com.datadog.iast.taint.TaintedObjects; import com.datadog.iast.util.RangeBuilder; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.propagation.CodecModule; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; import java.net.URI; import java.net.URL; import javax.annotation.Nonnull; @@ -29,14 +29,16 @@ public CodecModuleImpl() { @Override public void onUrlDecode( @Nonnull final String value, @Nullable final String encoding, @Nonnull final String result) { - propagationModule.taintStringIfTainted(result, value); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, value); } @Override public void onUrlEncode( @Nonnull final String value, @Nullable final String encoding, @Nonnull final String result) { // the new string should be safe to be used in - propagationModule.taintStringIfTainted(result, value, false, XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, value, false, XSS_MARK); } @Override @@ -47,41 +49,45 @@ public void onStringFromBytes( @Nullable final String charset, @Nonnull final String result) { // create a new range shifted to the result string coordinates - propagationModule.taintStringIfRangeTainted(result, value, offset, length, false, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfRangeTainted( + to, result, value, offset, length, false, NOT_MARKED); } @Override public void onStringGetBytes( @Nonnull final String value, @Nullable final String charset, @Nonnull final byte[] result) { - propagationModule.taintObjectIfTainted(result, value); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, value); } @Override public void onBase64Encode(@Nullable byte[] value, @Nullable byte[] result) { - propagationModule.taintObjectIfTainted(result, value); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, value); } @Override public void onBase64Decode(@Nullable byte[] value, @Nullable byte[] result) { - propagationModule.taintObjectIfTainted(result, value); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, value); } @Override public void onUriCreate(@Nonnull final URI result, final Object... args) { - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - taintUrlIfAnyTainted(ctx.getTaintedObjects(), result, args); + taintUrlIfAnyTainted(to, result, args); } @Override public void onUrlCreate(@Nonnull final URL result, final Object... args) { - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects to = ctx.getTaintedObjects(); if (args.length > 0 && args[0] instanceof URL) { final TaintedObject tainted = to.get(args[0]); if (tainted != null) { @@ -119,7 +125,7 @@ private void taintUrlIfAnyTainted( } if (builder.isEmpty()) { // no mappings of tainted values in the URL, resort to fully tainting it - propagationModule.taintObjectIfAnyTainted(url, args); + propagationModule.taintObjectIfAnyTainted(to, url, args); } else { to.taint(url, builder.toArray()); } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/PropagationModuleImpl.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/PropagationModuleImpl.java index e0d1668d6fd..12939bcf8d3 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/PropagationModuleImpl.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/PropagationModuleImpl.java @@ -1,21 +1,22 @@ package com.datadog.iast.propagation; -import static com.datadog.iast.model.Source.PROPAGATION_PLACEHOLDER; +import static com.datadog.iast.model.SourceImpl.PROPAGATION_PLACEHOLDER; import static com.datadog.iast.taint.Ranges.highestPriorityRange; import static com.datadog.iast.util.ObjectVisitor.State.CONTINUE; import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; +import com.datadog.iast.model.RangeImpl; +import com.datadog.iast.model.SourceImpl; import com.datadog.iast.taint.Ranges; -import com.datadog.iast.taint.TaintedObject; -import com.datadog.iast.taint.TaintedObjects; import com.datadog.iast.util.ObjectVisitor; -import com.datadog.iast.util.Ranged; import datadog.trace.api.Config; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.Taintable; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; +import datadog.trace.api.iast.util.Ranged; import java.lang.ref.WeakReference; import java.util.function.Predicate; import javax.annotation.Nonnull; @@ -28,113 +29,37 @@ public class PropagationModuleImpl implements PropagationModule { private static final int MAX_VALUE_LENGTH = Config.get().getIastTruncationMaxValueLength(); @Override - public void taintObject(@Nullable Object target, byte origin) { - taintObject(target, origin, null); - } - - @Override - public void taintObject(@Nullable IastContext ctx, @Nullable Object target, byte origin) { - taintObject(ctx, target, origin, null); - } - - @Override - public void taintString(@Nullable String target, byte origin) { - taintString(target, origin, null); - } - - @Override - public void taintString(@Nullable IastContext ctx, @Nullable String target, byte origin) { - taintString(ctx, target, origin, null); - } - - @Override - public void taintObject(@Nullable Object target, byte origin, @Nullable CharSequence name) { - taintObject(target, origin, name, target); + public void taintObject(@Nullable final TaintedObjects to, @Nullable Object target, byte origin) { + taintObject(to, target, origin, null); } @Override public void taintObject( - @Nullable IastContext ctx, + @Nullable final TaintedObjects to, @Nullable Object target, byte origin, @Nullable CharSequence name) { - taintObject(ctx, target, origin, name, target); - } - - @Override - public void taintString(@Nullable String target, byte origin, @Nullable CharSequence name) { - taintString(target, origin, name, target); - } - - @Override - public void taintString( - @Nullable IastContext ctx, - @Nullable String target, - byte origin, - @Nullable CharSequence name) { - taintString(ctx, target, origin, name, target); - } - - @Override - public void taintObjectRange( - @Nullable final Object target, final byte origin, final int start, final int length) { - if (target == null || length == 0) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObjectRange(ctx, target, origin, start, length); + taintObject(to, target, origin, name, target); } @Override public void taintObjectRange( - @Nullable final IastContext ctx, + @Nullable final TaintedObjects to, @Nullable final Object target, final byte origin, final int start, final int length) { - if (ctx == null || target == null || length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); - final Range range = - new Range(start, length, newSource(target, origin, null, target), NOT_MARKED); - internalTaint(to, target, new Range[] {range}, NOT_MARKED); - } - - @Override - public void taintStringRange( - @Nullable final String target, final byte origin, final int start, final int length) { if (target == null || length == 0) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintStringRange(ctx, target, origin, start, length); - } - - @Override - public void taintStringRange( - @Nullable final IastContext ctx, - @Nullable final String target, - final byte origin, - final int start, - final int length) { - if (ctx == null || target == null || length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); final Range range = - new Range(start, length, newSource(target, origin, null, target), NOT_MARKED); + new RangeImpl(start, length, newSource(target, origin, null, target), NOT_MARKED); internalTaint(to, target, new Range[] {range}, NOT_MARKED); } @Override public void taintObject( + @Nullable final TaintedObjects to, @Nullable final Object target, final byte origin, @Nullable final CharSequence name, @@ -142,134 +67,25 @@ public void taintObject( if (target == null) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObject(ctx, target, origin, name, value); - } - - @Override - public void taintObject( - @Nullable final IastContext ctx, - @Nullable final Object target, - final byte origin, - @Nullable final CharSequence name, - @Nullable final Object value) { - if (ctx == null || target == null) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); - internalTaint(to, target, newSource(target, origin, name, value), NOT_MARKED); - } - - @Override - public void taintString( - @Nullable final String target, - final byte origin, - @Nullable final CharSequence name, - @Nullable final CharSequence value) { - if (target == null) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintString(ctx, target, origin, name, value); - } - - @Override - public void taintString( - @Nullable final IastContext ctx, - @Nullable final String target, - final byte origin, - @Nullable final CharSequence name, - @Nullable final CharSequence value) { - if (ctx == null || target == null) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); internalTaint(to, target, newSource(target, origin, name, value), NOT_MARKED); } - @Override - public void taintObjectIfTainted(@Nullable Object target, @Nullable Object input) { - taintObjectIfTainted(target, input, false, NOT_MARKED); - } - @Override public void taintObjectIfTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object input) { - taintObjectIfTainted(ctx, target, input, false, NOT_MARKED); - } - - @Override - public void taintStringIfTainted(@Nullable String target, @Nullable Object input) { - taintStringIfTainted(target, input, false, NOT_MARKED); - } - - @Override - public void taintStringIfTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object input) { - taintStringIfTainted(ctx, target, input, false, NOT_MARKED); + @Nullable final TaintedObjects to, @Nullable Object target, @Nullable Object input) { + taintObjectIfTainted(to, target, input, false, NOT_MARKED); } @Override public void taintObjectIfTainted( - @Nullable final Object target, @Nullable final Object input, boolean keepRanges, int mark) { - if (target == null || input == null) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObjectIfTainted(ctx, target, input, keepRanges, mark); - } - - @Override - public void taintObjectIfTainted( - @Nullable final IastContext ctx, + @Nullable final TaintedObjects to, @Nullable final Object target, @Nullable final Object input, boolean keepRanges, int mark) { - if (ctx == null || target == null || input == null) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); - if (keepRanges) { - internalTaint(to, target, getRanges(to, input), mark); - } else { - internalTaint(to, target, highestPrioritySource(to, input), mark); - } - } - - @Override - public void taintStringIfTainted( - @Nullable final String target, @Nullable final Object input, boolean keepRanges, int mark) { if (target == null || input == null) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintStringIfTainted(ctx, target, input, keepRanges, mark); - } - - @Override - public void taintStringIfTainted( - @Nullable final IastContext ctx, - @Nullable final String target, - @Nullable final Object input, - boolean keepRanges, - int mark) { - if (ctx == null || target == null || input == null) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); if (keepRanges) { internalTaint(to, target, getRanges(to, input), mark); } else { @@ -279,6 +95,7 @@ public void taintStringIfTainted( @Override public void taintObjectIfRangeTainted( + @Nullable final TaintedObjects to, @Nullable final Object target, @Nullable final Object input, final int start, @@ -288,26 +105,6 @@ public void taintObjectIfRangeTainted( if (target == null || input == null || length == 0) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObjectIfRangeTainted(ctx, target, input, start, length, keepRanges, mark); - } - - @Override - public void taintObjectIfRangeTainted( - @Nullable final IastContext ctx, - @Nullable final Object target, - @Nullable final Object input, - final int start, - final int length, - boolean keepRanges, - int mark) { - if (ctx == null || target == null || input == null || length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); final Range[] ranges = getRanges(to, input); if (ranges == null || ranges.length == 0) { return; @@ -324,109 +121,28 @@ public void taintObjectIfRangeTainted( } } - @Override - public void taintStringIfRangeTainted( - @Nullable final String target, - @Nullable final Object input, - final int start, - final int length, - boolean keepRanges, - int mark) { - if (target == null || input == null || length == 0) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintStringIfRangeTainted(ctx, target, input, start, length, keepRanges, mark); - } - - @Override - public void taintStringIfRangeTainted( - @Nullable final IastContext ctx, - @Nullable final String target, - @Nullable final Object input, - final int start, - final int length, - boolean keepRanges, - int mark) { - if (ctx == null || target == null || input == null || length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); - final Range[] ranges = getRanges(to, input); - if (ranges == null || ranges.length == 0) { - return; - } - final Range[] intersection = Ranges.intersection(Ranged.build(start, length), ranges); - if (intersection == null || intersection.length == 0) { - return; - } - if (keepRanges) { - internalTaint(to, target, intersection, mark); - } else { - final Range range = highestPriorityRange(intersection); - internalTaint(to, target, range.getSource(), mark); - } - } - - @Override - public void taintObjectIfTainted(@Nullable Object target, @Nullable Object input, byte origin) { - taintObjectIfTainted(target, input, origin, null, target); - } - - @Override - public void taintObjectIfTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object input, byte origin) { - taintObjectIfTainted(ctx, target, input, origin, null, target); - } - - @Override - public void taintStringIfTainted(@Nullable String target, @Nullable Object input, byte origin) { - taintStringIfTainted(target, input, origin, null, target); - } - - @Override - public void taintStringIfTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object input, byte origin) { - taintStringIfTainted(ctx, target, input, origin, null, target); - } - @Override public void taintObjectIfTainted( - @Nullable Object target, @Nullable Object input, byte origin, @Nullable CharSequence name) { - taintObjectIfTainted(target, input, origin, name, target); - } - - @Override - public void taintObjectIfTainted( - @Nullable IastContext ctx, + @Nullable final TaintedObjects to, @Nullable Object target, @Nullable Object input, - byte origin, - @Nullable CharSequence name) { - taintObjectIfTainted(ctx, target, input, origin, name, target); + byte origin) { + taintObjectIfTainted(to, target, input, origin, null, target); } @Override - public void taintStringIfTainted( - @Nullable String target, @Nullable Object input, byte origin, @Nullable CharSequence name) { - taintStringIfTainted(target, input, origin, name, target); - } - - @Override - public void taintStringIfTainted( - @Nullable IastContext ctx, - @Nullable String target, + public void taintObjectIfTainted( + @Nullable final TaintedObjects to, + @Nullable Object target, @Nullable Object input, byte origin, @Nullable CharSequence name) { - taintStringIfTainted(ctx, target, input, origin, name, target); + taintObjectIfTainted(to, target, input, origin, name, target); } @Override public void taintObjectIfTainted( + @Nullable final TaintedObjects to, @Nullable final Object target, @Nullable final Object input, final byte origin, @@ -435,153 +151,27 @@ public void taintObjectIfTainted( if (target == null || input == null) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObjectIfTainted(ctx, target, input, origin, name, value); - } - - @Override - public void taintObjectIfTainted( - @Nullable final IastContext ctx, - @Nullable final Object target, - @Nullable final Object input, - final byte origin, - @Nullable final CharSequence name, - @Nullable final Object value) { - if (ctx == null || target == null || input == null) { - return; - } - if (isTainted(ctx, target)) { - final TaintedObjects to = ctx.getTaintedObjects(); + if (isTainted(to, input)) { internalTaint(to, target, newSource(target, origin, name, value), NOT_MARKED); } } - @Override - public void taintStringIfTainted( - @Nullable final String target, - @Nullable final Object input, - final byte origin, - @Nullable final CharSequence name, - @Nullable final Object value) { - if (target == null || input == null) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintStringIfTainted(ctx, target, input, origin, name, value); - } - - @Override - public void taintStringIfTainted( - @Nullable final IastContext ctx, - @Nullable final String target, - @Nullable final Object input, - final byte origin, - @Nullable final CharSequence name, - @Nullable final Object value) { - if (ctx == null || target == null || input == null) { - return; - } - if (isTainted(ctx, input)) { - final TaintedObjects to = ctx.getTaintedObjects(); - internalTaint(to, target, newSource(target, origin, name, value), NOT_MARKED); - } - } - - @Override - public void taintObjectIfAnyTainted(@Nullable Object target, @Nullable Object[] inputs) { - taintObjectIfAnyTainted(target, inputs, false, NOT_MARKED); - } - @Override public void taintObjectIfAnyTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object[] inputs) { - taintObjectIfAnyTainted(ctx, target, inputs, false, NOT_MARKED); - } - - @Override - public void taintStringIfAnyTainted(@Nullable String target, @Nullable Object[] inputs) { - taintStringIfAnyTainted(target, inputs, false, NOT_MARKED); - } - - @Override - public void taintStringIfAnyTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object[] inputs) { - taintStringIfAnyTainted(ctx, target, inputs, false, NOT_MARKED); - } - - @Override - public void taintObjectIfAnyTainted( - @Nullable final Object target, - @Nullable final Object[] inputs, - final boolean keepRanges, - final int mark) { - if (target == null || inputs == null || inputs.length == 0) { - return; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintObjectIfAnyTainted(ctx, target, inputs, keepRanges, mark); + @Nullable final TaintedObjects to, @Nullable Object target, @Nullable Object[] inputs) { + taintObjectIfAnyTainted(to, target, inputs, false, NOT_MARKED); } @Override public void taintObjectIfAnyTainted( - @Nullable final IastContext ctx, + @Nullable final TaintedObjects to, @Nullable final Object target, @Nullable final Object[] inputs, final boolean keepRanges, final int mark) { - if (ctx == null || target == null || inputs == null || inputs.length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); - if (keepRanges) { - final Range[] ranges = getRangesInArray(to, inputs); - if (ranges != null) { - internalTaint(to, target, ranges, mark); - } - } else { - final Source source = highestPrioritySourceInArray(to, inputs); - if (source != null) { - internalTaint(to, target, source, mark); - } - } - } - - @Override - public void taintStringIfAnyTainted( - @Nullable final String target, - @Nullable final Object[] inputs, - final boolean keepRanges, - final int mark) { if (target == null || inputs == null || inputs.length == 0) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return; - } - taintStringIfAnyTainted(ctx, target, inputs, keepRanges, mark); - } - - @Override - public void taintStringIfAnyTainted( - @Nullable final IastContext ctx, - @Nullable final String target, - @Nullable final Object[] inputs, - final boolean keepRanges, - final int mark) { - if (ctx == null || target == null || inputs == null || inputs.length == 0) { - return; - } - final TaintedObjects to = ctx.getTaintedObjects(); if (keepRanges) { final Range[] ranges = getRangesInArray(to, inputs); if (ranges != null) { @@ -597,27 +187,13 @@ public void taintStringIfAnyTainted( @Override public int taintObjectDeeply( - @Nullable final Object target, final byte origin, final Predicate> classFilter) { - if (target == null) { - return 0; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return 0; - } - return taintObjectDeeply(ctx, target, origin, classFilter); - } - - @Override - public int taintObjectDeeply( - @Nullable final IastContext ctx, + @Nullable final TaintedObjects to, @Nullable final Object target, final byte origin, final Predicate> classFilter) { - if (ctx == null || target == null) { + if (to == null || target == null) { return 0; } - final TaintedObjects to = ctx.getTaintedObjects(); if (target instanceof CharSequence) { internalTaint(to, target, newSource(target, origin, null, target), NOT_MARKED); return 1; @@ -630,43 +206,16 @@ public int taintObjectDeeply( @Nullable @Override - public Taintable.Source findSource(@Nullable final Object target) { + public Source findSource(@Nullable final TaintedObjects to, @Nullable final Object target) { if (target == null) { return null; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return null; - } - return findSource(ctx, target); - } - - @Nullable - @Override - public Taintable.Source findSource( - @Nullable final IastContext ctx, @Nullable final Object target) { - if (ctx == null || target == null) { - return null; - } - final TaintedObjects to = ctx.getTaintedObjects(); return highestPrioritySource(to, target); } @Override - public boolean isTainted(@Nullable final Object target) { - if (target == null) { - return false; - } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { - return false; - } - return isTainted(ctx, target); - } - - @Override - public boolean isTainted(@Nullable final IastContext ctx, @Nullable final Object target) { - return ctx != null && target != null && findSource(ctx, target) != null; + public boolean isTainted(@Nullable final TaintedObjects to, @Nullable final Object target) { + return target != null && findSource(to, target) != null; } /** @@ -680,21 +229,7 @@ private static Source newSource( @Nullable final Object value) { final Object sourceValue = sourceReference(target, value, true); final Object sourceName = name == value ? sourceValue : sourceReference(target, name, false); - return new Source(origin, sourceName, sourceValue); - } - - /** - * Ensures that the reference is not kept due to a strong reference via the name or value - * properties - */ - private static Source newSource( - @Nonnull final String tainted, - final byte origin, - @Nullable final CharSequence name, - @Nullable final CharSequence value) { - final Object sourceValue = sourceReference(tainted, value, true); - final Object sourceName = name == value ? sourceValue : sourceReference(tainted, name, false); - return new Source(origin, sourceName, sourceValue); + return new SourceImpl(origin, sourceName, sourceValue); } /** @@ -721,7 +256,7 @@ private static Object sourceReference( @Nullable private static Range[] getRangesInArray( - final @Nonnull TaintedObjects to, final @Nonnull Object[] objects) { + final @Nullable TaintedObjects to, final @Nonnull Object[] objects) { for (final Object object : objects) { final Range[] ranges = getRanges(to, object); if (ranges != null) { @@ -732,22 +267,26 @@ private static Range[] getRangesInArray( } @Nullable - private static Range[] getRanges(final @Nonnull TaintedObjects to, final @Nonnull Object object) { + private static Range[] getRanges( + final @Nullable TaintedObjects to, final @Nonnull Object object) { if (object instanceof Taintable) { final Source source = highestPrioritySource(to, object); if (source == null) { return null; } else { - return new Range[] {new Range(0, Integer.MAX_VALUE, source, NOT_MARKED)}; + return new Range[] {new RangeImpl(0, Integer.MAX_VALUE, source, NOT_MARKED)}; } + } else if (to != null) { + final TaintedObject tainted = to.get(object); + return tainted == null ? null : tainted.getRanges(); + } else { + return null; } - final TaintedObject tainted = to.get(object); - return tainted == null ? null : tainted.getRanges(); } @Nullable private static Source highestPrioritySourceInArray( - final @Nonnull TaintedObjects to, final @Nonnull Object[] objects) { + final @Nullable TaintedObjects to, final @Nonnull Object[] objects) { for (final Object object : objects) { final Source source = highestPrioritySource(to, object); if (source != null) { @@ -759,17 +298,19 @@ private static Source highestPrioritySourceInArray( @Nullable private static Source highestPrioritySource( - final @Nonnull TaintedObjects to, final @Nonnull Object object) { + final @Nullable TaintedObjects to, final @Nonnull Object object) { if (object instanceof Taintable) { - return (Source) ((Taintable) object).$$DD$getSource(); - } else { + return ((Taintable) object).$$DD$getSource(); + } else if (to != null) { final Range[] ranges = getRanges(to, object); return ranges != null && ranges.length > 0 ? highestPriorityRange(ranges).getSource() : null; + } else { + return null; } } private static void internalTaint( - @Nonnull final TaintedObjects to, + @Nullable final TaintedObjects to, @Nonnull final Object value, @Nullable Source source, int mark) { @@ -778,7 +319,7 @@ private static void internalTaint( } if (value instanceof Taintable) { ((Taintable) value).$$DD$setSource(source); - } else { + } else if (to != null) { if (value instanceof CharSequence) { source = attachSourceValue(source, (CharSequence) value); to.taint(value, Ranges.forCharSequence((CharSequence) value, source, mark)); @@ -789,19 +330,7 @@ private static void internalTaint( } private static void internalTaint( - @Nonnull final TaintedObjects to, - @Nonnull final String value, - @Nullable Source source, - int mark) { - if (source == null) { - return; - } - source = attachSourceValue(source, value); - to.taint(value, Ranges.forCharSequence(value, source, mark)); - } - - private static void internalTaint( - @Nonnull final TaintedObjects to, + @Nullable final TaintedObjects to, @Nonnull final Object value, @Nullable Range[] ranges, final int mark) { @@ -813,7 +342,7 @@ private static void internalTaint( if (!taintable.$DD$isTainted()) { taintable.$$DD$setSource(ranges[0].getSource()); } - } else { + } else if (to != null) { if (value instanceof CharSequence) { ranges = attachSourceValue(ranges, (CharSequence) value); } @@ -830,27 +359,6 @@ private static void internalTaint( } } - private static void internalTaint( - @Nonnull final TaintedObjects to, - @Nonnull final String value, - @Nullable Range[] ranges, - final int mark) { - if (ranges == null || ranges.length == 0) { - return; - } - ranges = attachSourceValue(ranges, value); - ranges = markRanges(ranges, mark); - final TaintedObject tainted = to.get(value); - if (tainted != null) { - // append ranges - final Range[] newRanges = Ranges.mergeRangesSorted(tainted.getRanges(), ranges); - tainted.setRanges(newRanges); - } else { - // taint new value - to.taint(value, ranges); - } - } - @Nonnull private static Range[] markRanges(@Nonnull final Range[] ranges, final int mark) { if (mark == NOT_MARKED) { @@ -860,7 +368,7 @@ private static Range[] markRanges(@Nonnull final Range[] ranges, final int mark) for (int i = 0; i < ranges.length; i++) { final Range range = ranges[i]; final int newMark = range.getMarks() | mark; - result[i] = new Range(range.getStart(), range.getLength(), range.getSource(), newMark); + result[i] = new RangeImpl(range.getStart(), range.getLength(), range.getSource(), newMark); } return result; } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/StringModuleImpl.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/StringModuleImpl.java index 4ef50cb6b1e..197f6c8c628 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/StringModuleImpl.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/propagation/StringModuleImpl.java @@ -7,17 +7,18 @@ import static com.datadog.iast.taint.Tainteds.getTainted; import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY; -import com.datadog.iast.model.Range; -import com.datadog.iast.model.Source; +import com.datadog.iast.model.SourceImpl; import com.datadog.iast.taint.Ranges; -import com.datadog.iast.taint.TaintedObject; -import com.datadog.iast.taint.TaintedObjects; import com.datadog.iast.util.RangeBuilder; -import com.datadog.iast.util.Ranged; import com.datadog.iast.util.StringUtils; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.Taintable; import datadog.trace.api.iast.propagation.StringModule; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; +import datadog.trace.api.iast.util.Ranged; import de.thetaphi.forbiddenapis.SuppressForbidden; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Arrays; @@ -58,13 +59,12 @@ public void onStringConcat( if (!canBeTainted(left) && !canBeTainted(right)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedLeft = getTainted(taintedObjects, left); - final TaintedObject taintedRight = getTainted(taintedObjects, right); + final TaintedObject taintedLeft = getTainted(to, left); + final TaintedObject taintedRight = getTainted(to, right); if (taintedLeft == null && taintedRight == null) { return; } @@ -77,7 +77,7 @@ public void onStringConcat( } else { ranges = mergeRanges(left.length(), taintedLeft.getRanges(), taintedRight.getRanges()); } - taintedObjects.taint(result, ranges); + to.taint(result, ranges); } @Override @@ -86,16 +86,15 @@ public void onStringBuilderInit( if (!canBeTainted(param)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject paramTainted = taintedObjects.get(param); + final TaintedObject paramTainted = to.get(param); if (paramTainted == null) { return; } - taintedObjects.taint(builder, paramTainted.getRanges()); + to.taint(builder, paramTainted.getRanges()); } @Override @@ -104,22 +103,21 @@ public void onStringBuilderAppend( if (!canBeTainted(builder) || !canBeTainted(param)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject paramTainted = taintedObjects.get(param); + final TaintedObject paramTainted = to.get(param); if (paramTainted == null) { return; } - final TaintedObject builderTainted = taintedObjects.get(builder); + final TaintedObject builderTainted = to.get(builder); final int shift = builder.length() - param.length(); if (builderTainted == null) { final Range[] paramRanges = paramTainted.getRanges(); final Range[] ranges = new Range[paramRanges.length]; Ranges.copyShift(paramRanges, ranges, 0, shift); - taintedObjects.taint(builder, ranges); + to.taint(builder, ranges); } else { final Range[] builderRanges = builderTainted.getRanges(); final Range[] paramRanges = paramTainted.getRanges(); @@ -134,16 +132,15 @@ public void onStringBuilderToString( if (!canBeTainted(builder) || !canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject to = taintedObjects.get(builder); - if (to == null) { + final TaintedObject tainted = to.get(builder); + if (tainted == null) { return; } - taintedObjects.taint(result, to.getRanges()); + to.taint(result, tainted.getRanges()); } @Override @@ -156,12 +153,11 @@ public void onStringConcatFactory( if (!canBeTainted(result) || !canBeTainted(args)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); final RangeBuilder targetRanges = new RangeBuilder(); int offset = 0; for (int item : recipeOffsets) { @@ -169,7 +165,7 @@ public void onStringConcatFactory( offset += -item; } else { final String argument = args[item]; - final Range[] ranges = getRanges(getTainted(taintedObjects, argument)); + final Range[] ranges = getRanges(getTainted(to, argument)); if (ranges.length > 0) { targetRanges.add(ranges, offset); if (targetRanges.isFull()) { @@ -180,7 +176,7 @@ public void onStringConcatFactory( } } if (!targetRanges.isEmpty()) { - taintedObjects.taint(result, targetRanges.toArray()); + to.taint(result, targetRanges.toArray()); } } @@ -191,12 +187,11 @@ public void onStringSubSequence( if (self == result || !canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject selfTainted = taintedObjects.get(self); + final TaintedObject selfTainted = to.get(self); if (selfTainted == null) { return; } @@ -206,7 +201,7 @@ public void onStringSubSequence( } Range[] newRanges = Ranges.forSubstring(beginIndex, result.length(), rangesSelf); if (newRanges != null && newRanges.length > 0) { - taintedObjects.taint(result, newRanges); + to.taint(result, newRanges); } } @@ -216,22 +211,21 @@ public void onStringJoin( if (!canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); // String.join may internally call StringJoiner, if StringJoiner did the job don't do it twice - if (getTainted(taintedObjects, result) != null) { + if (getTainted(to, result) != null) { return; } - final Range[] delimiterRanges = getRanges(getTainted(taintedObjects, delimiter)); + final Range[] delimiterRanges = getRanges(getTainted(to, delimiter)); final RangeBuilder targetRanges = new RangeBuilder(); int delimiterLength = getToStringLength(delimiter), offset = 0; for (int i = 0; i < elements.length; i++) { // insert element ranges final CharSequence element = elements[i]; - final Range[] ranges = getRanges(getTainted(taintedObjects, element)); + final Range[] ranges = getRanges(getTainted(to, element)); if (ranges.length > 0) { targetRanges.add(ranges, offset); if (targetRanges.isFull()) { @@ -250,7 +244,7 @@ public void onStringJoin( } } if (!targetRanges.isEmpty()) { - taintedObjects.taint(result, targetRanges.toArray()); + to.taint(result, targetRanges.toArray()); } } @@ -260,12 +254,11 @@ public void onStringRepeat(@Nonnull String self, int count, @Nonnull String resu if (!canBeTainted(self) || !canBeTainted(result) || self == result) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final Range[] selfRanges = getRanges(taintedObjects.get(self)); + final Range[] selfRanges = getRanges(to.get(self)); if (selfRanges.length == 0) { return; } @@ -277,7 +270,7 @@ public void onStringRepeat(@Nonnull String self, int count, @Nonnull String resu break; } } - taintedObjects.taint(result, ranges); + to.taint(result, ranges); } private static int getToStringLength(@Nullable final CharSequence s) { @@ -302,12 +295,11 @@ public void onStringCaseChanged(@Nonnull String self, @Nullable String result) { if (self == result) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); if (taintedSelf == null) { return; } @@ -316,14 +308,14 @@ public void onStringCaseChanged(@Nonnull String self, @Nullable String result) { return; } if (result.length() == self.length()) { - taintedObjects.taint(result, rangesSelf); + to.taint(result, rangesSelf); return; } if (result.length() >= self.length()) { - taintedObjects.taint(result, rangesSelf); + to.taint(result, rangesSelf); } // Pathological case where the string's length actually becomes smaller else { - stringCaseChangedWithReducedSize(rangesSelf, taintedObjects, result); + stringCaseChangedWithReducedSize(rangesSelf, to, result); } } @@ -375,12 +367,11 @@ public void onStringTrim(@Nonnull final String self, @Nullable final String resu if (self == result) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); if (taintedSelf == null) { return; } @@ -400,7 +391,7 @@ public void onStringTrim(@Nonnull final String self, @Nullable final String resu final Range[] newRanges = Ranges.forSubstring(offset, resultLength, rangesSelf); if (null != newRanges) { - taintedObjects.taint(result, newRanges); + to.taint(result, newRanges); } } @@ -409,16 +400,15 @@ public void onStringConstructor(@Nonnull CharSequence self, @Nonnull String resu if (!canBeTainted(self)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final Range[] selfRanges = getRanges(taintedObjects.get(self)); + final Range[] selfRanges = getRanges(to.get(self)); if (selfRanges.length == 0) { return; } - taintedObjects.taint(result, selfRanges); + to.taint(result, selfRanges); } @Override @@ -436,11 +426,10 @@ public void onStringFormat( if (!canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects to = ctx.getTaintedObjects(); final Deque formatRanges = new LinkedList<>(); final TaintedObject formatTainted = to.get(format); if (formatTainted != null) { @@ -519,11 +508,10 @@ public void onStringFormat( if (!canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects to = ctx.getTaintedObjects(); // since we might join ranges the final number is unknown beforehand final RangeBuilder finalRanges = new RangeBuilder(); int offset = 0, paramIndex = 0; @@ -556,11 +544,10 @@ public void onSplit(@Nonnull String self, @Nonnull String[] result) { if (result.length == 1 && result[0] == self) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects to = ctx.getTaintedObjects(); TaintedObject taintedString = to.get(self); if (taintedString == null) { return; @@ -577,12 +564,11 @@ public void onStringStrip(@Nonnull String self, @Nonnull String result, boolean if (self == result || !canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); if (taintedSelf == null) { return; } @@ -604,7 +590,7 @@ public void onStringStrip(@Nonnull String self, @Nonnull String result, boolean final Range[] newRanges = Ranges.forSubstring(offset, resultLength, rangesSelf); if (newRanges != null) { - taintedObjects.taint(result, newRanges); + to.taint(result, newRanges); } } @@ -614,12 +600,11 @@ public void onIndent(@Nonnull String self, int indentation, @Nonnull String resu if (self == result || !canBeTainted(self)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); if (taintedSelf == null) { return; } @@ -631,7 +616,7 @@ public void onIndent(@Nonnull String self, int indentation, @Nonnull String resu final Range[] newRanges = Ranges.forIndentation(self, indentation, rangesSelf); if (newRanges != null) { - taintedObjects.taint(result, newRanges); + to.taint(result, newRanges); } } @@ -642,12 +627,11 @@ public void onStringReplace( if (self == result || !canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); if (taintedSelf == null) { return; } @@ -657,7 +641,7 @@ public void onStringReplace( return; } - taintedObjects.taint(result, rangesSelf); + to.taint(result, rangesSelf); } /** This method is used to make an {@code CallSite.Around} of the {@code String.replace} method */ @@ -665,18 +649,17 @@ public void onStringReplace( @SuppressFBWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ") public String onStringReplace( @Nonnull String self, CharSequence oldCharSeq, CharSequence newCharSeq) { - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return self.replace(oldCharSeq, newCharSeq); } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); Range[] rangesSelf = new Range[0]; if (taintedSelf != null) { rangesSelf = taintedSelf.getRanges(); } - final TaintedObject taintedInput = taintedObjects.get(newCharSeq); + final TaintedObject taintedInput = to.get(newCharSeq); Range[] rangesInput = null; if (taintedInput != null) { rangesInput = taintedInput.getRanges(); @@ -687,7 +670,7 @@ public String onStringReplace( } return StringUtils.replaceAndTaint( - taintedObjects, + to, self, Pattern.compile((String) oldCharSeq), (String) newCharSeq, @@ -704,8 +687,8 @@ public String onStringReplace( @SuppressForbidden public String onStringReplace( @Nonnull String self, String regex, String replacement, int numReplacements) { - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { if (numReplacements > 1) { return self.replaceAll(regex, replacement); } else { @@ -713,14 +696,13 @@ public String onStringReplace( } } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); - final TaintedObject taintedSelf = taintedObjects.get(self); + final TaintedObject taintedSelf = to.get(self); Range[] rangesSelf = new Range[0]; if (taintedSelf != null) { rangesSelf = taintedSelf.getRanges(); } - final TaintedObject taintedInput = taintedObjects.get(replacement); + final TaintedObject taintedInput = to.get(replacement); Range[] rangesInput = null; if (taintedInput != null) { rangesInput = taintedInput.getRanges(); @@ -735,13 +717,7 @@ public String onStringReplace( } return StringUtils.replaceAndTaint( - taintedObjects, - self, - Pattern.compile(regex), - replacement, - rangesSelf, - rangesInput, - numReplacements); + to, self, Pattern.compile(regex), replacement, rangesSelf, rangesInput, numReplacements); } @Override @@ -750,25 +726,24 @@ public void onStringValueOf(Object param, @Nonnull String result) { if (param == null || !canBeTainted(result)) { return; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return; } - final TaintedObjects taintedObjects = ctx.getTaintedObjects(); if (param instanceof Taintable) { final Taintable taintable = (Taintable) param; if (!taintable.$DD$isTainted()) { return; } - final Source source = (Source) taintable.$$DD$getSource(); + final Source source = taintable.$$DD$getSource(); final Range[] ranges = Ranges.forCharSequence( - result, new Source(source.getOrigin(), source.getName(), source.getValue())); + result, new SourceImpl(source.getOrigin(), source.getName(), source.getValue())); - taintedObjects.taint(result, ranges); + to.taint(result, ranges); } else { - final TaintedObject taintedParam = taintedObjects.get(param); + final TaintedObject taintedParam = to.get(param); if (taintedParam == null) { return; } @@ -783,11 +758,11 @@ public void onStringValueOf(Object param, @Nonnull String result) { final Source source = rangesParam[0].getSource(); final Range[] ranges = Ranges.forCharSequence( - result, new Source(source.getOrigin(), source.getName(), source.getValue())); + result, new SourceImpl(source.getOrigin(), source.getName(), source.getValue())); - taintedObjects.taint(result, ranges); + to.taint(result, ranges); } else { - taintedObjects.taint(result, rangesParam); + to.taint(result, rangesParam); } } } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/AbstractRegexTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/AbstractRegexTokenizer.java index 54c73669be3..aa9e57680b9 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/AbstractRegexTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/AbstractRegexTokenizer.java @@ -1,6 +1,6 @@ package com.datadog.iast.sensitive; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.NoSuchElementException; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/CommandRegexpTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/CommandRegexpTokenizer.java index 970239e0207..ad35fe2afcf 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/CommandRegexpTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/CommandRegexpTokenizer.java @@ -1,7 +1,7 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.regex.Pattern; public class CommandRegexpTokenizer extends AbstractRegexTokenizer { diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/HeaderRegexpTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/HeaderRegexpTokenizer.java index 69e34773eb8..9a112faa563 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/HeaderRegexpTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/HeaderRegexpTokenizer.java @@ -1,7 +1,7 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.NoSuchElementException; import java.util.regex.Pattern; import javax.annotation.Nullable; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/LdapRegexTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/LdapRegexTokenizer.java index 72ec3e70d86..a226461c42c 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/LdapRegexTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/LdapRegexTokenizer.java @@ -1,7 +1,7 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.regex.Pattern; /** diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandler.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandler.java index b44415852e3..dfbdfd16fa8 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandler.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandler.java @@ -1,9 +1,9 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.model.Source; import com.datadog.iast.model.VulnerabilityType; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.util.Ranged; import java.util.NoSuchElementException; import javax.annotation.Nonnull; import javax.annotation.Nullable; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandlerImpl.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandlerImpl.java index c0a500e9de6..6a5c56cb892 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandlerImpl.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SensitiveHandlerImpl.java @@ -7,9 +7,9 @@ import static java.util.regex.Pattern.MULTILINE; import com.datadog.iast.model.Evidence; -import com.datadog.iast.model.Source; import com.datadog.iast.model.VulnerabilityType; import datadog.trace.api.Config; +import datadog.trace.api.iast.taint.Source; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SqlRegexpTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SqlRegexpTokenizer.java index 6c87aaf7a87..a5e449f3f7a 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SqlRegexpTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/SqlRegexpTokenizer.java @@ -3,7 +3,7 @@ import static datadog.trace.api.iast.sink.SqlInjectionModule.DATABASE_PARAMETER; import com.datadog.iast.model.Evidence; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.*; import java.util.function.Predicate; import java.util.function.Supplier; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/TaintedRangeBasedTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/TaintedRangeBasedTokenizer.java index b2cff3356b4..e8fa679d1f3 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/TaintedRangeBasedTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/TaintedRangeBasedTokenizer.java @@ -1,9 +1,9 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.model.Range; import com.datadog.iast.taint.Ranges; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.util.Ranged; import java.util.NoSuchElementException; import javax.annotation.Nullable; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/UrlRegexpTokenizer.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/UrlRegexpTokenizer.java index 9f81d172f92..73d8ddbb8c0 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/UrlRegexpTokenizer.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sensitive/UrlRegexpTokenizer.java @@ -1,7 +1,7 @@ package com.datadog.iast.sensitive; import com.datadog.iast.model.Evidence; -import com.datadog.iast.util.Ranged; +import datadog.trace.api.iast.util.Ranged; import java.util.regex.Pattern; /** @see { - - Logger LOGGER = LoggerFactory.getLogger(TaintedObjects.class); - - static TaintedObjects build(@Nonnull final TaintedMap map) { - final TaintedObjectsImpl taintedObjects = new TaintedObjectsImpl(map); - return IastSystem.DEBUG ? new TaintedObjectsDebugAdapter(taintedObjects) : taintedObjects; - } - - @Nullable - TaintedObject taint(@Nonnull Object obj, @Nonnull Range[] ranges); - - @Nullable - TaintedObject get(@Nonnull Object obj); - - void clear(); - - int count(); - - class TaintedObjectsImpl implements TaintedObjects { - - private final TaintedMap map; - - private TaintedObjectsImpl(final @Nonnull TaintedMap map) { - this.map = map; - } - - @Nullable - @Override - public TaintedObject taint(final @Nonnull Object obj, final @Nonnull Range[] ranges) { - try { - final TaintedObject tainted = new TaintedObject(obj, ranges); - map.put(tainted); - return tainted; - } catch (Throwable e) { - LOGGER.debug("Error tainting object, it won't be tainted", e); - return null; - } - } - - @Nullable - @Override - public TaintedObject get(final @Nonnull Object obj) { - return map.get(obj); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public int count() { - return map.count(); - } - - @Nonnull - @Override - public Iterator iterator() { - return map.iterator(); - } - } - - final class TaintedObjectsDebugAdapter implements TaintedObjects, Wrapper { - - private final TaintedObjectsImpl delegated; - private final UUID id; - - public TaintedObjectsDebugAdapter(final TaintedObjectsImpl delegated) { - this.delegated = delegated; - id = UUID.randomUUID(); - LOGGER.debug("new: id={}", id); - } - - @Nullable - @Override - public TaintedObject taint(final @Nonnull Object obj, final @Nonnull Range[] ranges) { - final TaintedObject tainted = delegated.taint(obj, ranges); - logTainted(tainted); - return tainted; - } - - @Nullable - @Override - public TaintedObject get(final @Nonnull Object obj) { - return delegated.get(obj); - } - - @Override - public void clear() { - if (IastSystem.DEBUG && LOGGER.isDebugEnabled()) { - try { - final List entries = new ArrayList<>(); - for (final TaintedObject to : delegated.map) { - entries.add(to); - } - LOGGER.debug("clear {}: map={}", id, TaintedObjectEncoding.toJson(entries)); - } catch (final Throwable e) { - LOGGER.error("Failed to debug tainted objects release", e); - } - } - delegated.clear(); - } - - @Override - public int count() { - return delegated.count(); - } - - @Nonnull - @Override - public Iterator iterator() { - return delegated.iterator(); - } - - private void logTainted(@Nullable final TaintedObject tainted) { - if (LOGGER.isDebugEnabled()) { - try { - if (tainted == null) { - LOGGER.debug("taint {}: ignored", id); - } else { - LOGGER.debug("taint {}: tainted={}", id, TaintedObjectEncoding.toJson(tainted)); - } - } catch (final Throwable e) { - LOGGER.error("Failed to debug new tainted object", e); - } - } - } - - @Override - public TaintedObjectsImpl unwrap() { - return delegated; - } - } - - final class NoOp implements TaintedObjects { - - public static final TaintedObjects INSTANCE = new NoOp(); - - @Nullable - @Override - public TaintedObject taint(@Nonnull final Object obj, @Nonnull final Range[] ranges) { - return null; - } - - @Nullable - @Override - public TaintedObject get(@Nonnull final Object obj) { - return null; - } - - @Override - public void clear() {} - - @Override - public int count() { - return 0; - } - - @Override - @Nonnull - public Iterator iterator() { - return emptyIterator(); - } - } -} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsDebugAdapter.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsDebugAdapter.java new file mode 100644 index 00000000000..decf4af9b68 --- /dev/null +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsDebugAdapter.java @@ -0,0 +1,96 @@ +package com.datadog.iast.taint; + +import com.datadog.iast.IastSystem; +import com.datadog.iast.model.json.TaintedObjectEncoding; +import com.datadog.iast.util.Wrapper; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import javax.annotation.Nonnull; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TaintedObjectsDebugAdapter implements TaintedObjects, Wrapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaintedObjectsDebugAdapter.class); + + private final TaintedObjects delegated; + private final UUID id; + + public TaintedObjectsDebugAdapter(final TaintedObjects delegated) { + this.delegated = delegated; + id = UUID.randomUUID(); + LOGGER.debug("new: id={}", id); + } + + @Nullable + @Override + public TaintedObject taint(final @Nonnull Object obj, final @Nonnull Range[] ranges) { + final TaintedObject tainted = delegated.taint(obj, ranges); + logTainted(tainted); + return tainted; + } + + @Nullable + @Override + public TaintedObject get(final @Nonnull Object obj) { + return delegated.get(obj); + } + + @Override + public boolean isTainted(@NotNull Object obj) { + return delegated.isTainted(obj); + } + + @Override + public void clear() { + if (IastSystem.DEBUG && LOGGER.isDebugEnabled()) { + try { + final List entries = new ArrayList<>(); + for (final TaintedObject to : delegated) { + entries.add(to); + } + LOGGER.debug("clear {}: map={}", id, TaintedObjectEncoding.toJson(entries)); + } catch (final Throwable e) { + LOGGER.error("Failed to debug tainted objects release", e); + } + } + delegated.clear(); + } + + @Override + public int count() { + return delegated.count(); + } + + @Nonnull + @Override + public Iterator iterator() { + return delegated.iterator(); + } + + private void logTainted(@Nullable final TaintedObject tainted) { + if (LOGGER.isDebugEnabled()) { + try { + if (tainted == null) { + LOGGER.debug("taint {}: ignored", id); + } else { + LOGGER.debug("taint {}: tainted={}", id, TaintedObjectEncoding.toJson(tainted)); + } + } catch (final Throwable e) { + LOGGER.error("Failed to debug new tainted object", e); + } + } + } + + @Override + public TaintedObjects unwrap() { + return delegated; + } +} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsMap.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsMap.java new file mode 100644 index 00000000000..8d6493c17d2 --- /dev/null +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjectsMap.java @@ -0,0 +1,69 @@ +package com.datadog.iast.taint; + +import com.datadog.iast.IastSystem; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; +import java.util.Iterator; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("UnusedReturnValue") +public class TaintedObjectsMap implements TaintedObjects { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaintedObjectsMap.class); + + public static TaintedObjects build(@Nonnull final TaintedMap map) { + final TaintedObjectsMap taintedObjects = new TaintedObjectsMap(map); + return IastSystem.DEBUG ? new TaintedObjectsDebugAdapter(taintedObjects) : taintedObjects; + } + + private final TaintedMap map; + + private TaintedObjectsMap(final @Nonnull TaintedMap map) { + this.map = map; + } + + @Nullable + @Override + public TaintedObject taint(final @Nonnull Object obj, final @Nonnull Range[] ranges) { + try { + final TaintedObjectEntry tainted = new TaintedObjectEntry(obj, ranges); + map.put(tainted); + return tainted; + } catch (Throwable e) { + LOGGER.debug("Error tainting object, it won't be tainted", e); + return null; + } + } + + @Nullable + @Override + public TaintedObject get(final @Nonnull Object obj) { + return map.get(obj); + } + + @Override + public boolean isTainted(@NotNull Object obj) { + return get(obj) != null; + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public int count() { + return map.count(); + } + + @Nonnull + @Override + public Iterator iterator() { + return map.iterator(); + } +} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/Tainteds.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/Tainteds.java index d4d6ac5fe36..a5a3c7d51ab 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/Tainteds.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/Tainteds.java @@ -1,5 +1,7 @@ package com.datadog.iast.taint; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.RandomAccess; import javax.annotation.Nonnull; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/TelemetryRequestStartedHandler.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/TelemetryRequestStartedHandler.java index 92dcf317886..30d1c72cba9 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/TelemetryRequestStartedHandler.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/TelemetryRequestStartedHandler.java @@ -3,9 +3,9 @@ import com.datadog.iast.Dependencies; import com.datadog.iast.IastRequestContext; import com.datadog.iast.RequestStartedHandler; -import com.datadog.iast.taint.TaintedObjects; import com.datadog.iast.telemetry.taint.TaintedObjectsWithTelemetry; import datadog.trace.api.Config; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.telemetry.IastMetricCollector; import datadog.trace.api.iast.telemetry.Verbosity; import javax.annotation.Nonnull; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetry.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetry.java index 14caf7fae4a..57f2769dae0 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetry.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetry.java @@ -3,16 +3,17 @@ import static datadog.trace.api.iast.telemetry.IastMetric.EXECUTED_TAINTED; import static datadog.trace.api.iast.telemetry.IastMetric.REQUEST_TAINTED; -import com.datadog.iast.model.Range; -import com.datadog.iast.taint.TaintedObject; -import com.datadog.iast.taint.TaintedObjects; import com.datadog.iast.util.Wrapper; import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.TaintedObject; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.telemetry.IastMetricCollector; import datadog.trace.api.iast.telemetry.Verbosity; import java.util.Iterator; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.jetbrains.annotations.NotNull; public class TaintedObjectsWithTelemetry implements TaintedObjects, Wrapper { @@ -51,6 +52,11 @@ public TaintedObject get(@Nonnull Object obj) { return delegate.get(obj); } + @Override + public boolean isTainted(@NotNull Object obj) { + return delegate.isTainted(obj); + } + @Override public void clear() { try { diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangeBuilder.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangeBuilder.java index 52fdcae97db..290a5797050 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangeBuilder.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangeBuilder.java @@ -1,10 +1,10 @@ package com.datadog.iast.util; -import com.datadog.iast.model.Range; import com.datadog.iast.taint.Ranges; -import com.datadog.iast.taint.TaintedObject; +import com.datadog.iast.taint.TaintedObjectEntry; import datadog.trace.api.Config; import datadog.trace.api.ConfigDefaults; +import datadog.trace.api.iast.taint.Range; import javax.annotation.Nullable; /** @@ -29,7 +29,7 @@ public class RangeBuilder { @Nullable protected Entry tail; public RangeBuilder() { - this(TaintedObject.MAX_RANGE_COUNT); + this(TaintedObjectEntry.MAX_RANGE_COUNT); } public RangeBuilder(final int maxSize) { diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangedDeque.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangedDeque.java index 4e66a2bf5a1..6470263f4d4 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangedDeque.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/RangedDeque.java @@ -1,6 +1,7 @@ package com.datadog.iast.util; import com.datadog.iast.sensitive.SensitiveHandler.Tokenizer; +import datadog.trace.api.iast.util.Ranged; import java.util.Deque; import java.util.LinkedList; import javax.annotation.Nonnull; diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/StringUtils.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/StringUtils.java index 86aa33ea576..fe49a0029af 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/StringUtils.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/StringUtils.java @@ -1,8 +1,8 @@ package com.datadog.iast.util; -import com.datadog.iast.model.Range; import com.datadog.iast.taint.Ranges; -import com.datadog.iast.taint.TaintedObjects; +import datadog.trace.api.iast.taint.Range; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nonnull; diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/GrpcRequestMessageHandlerTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/GrpcRequestMessageHandlerTest.groovy index b8b12ecbd89..5f3c2163ba6 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/GrpcRequestMessageHandlerTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/GrpcRequestMessageHandlerTest.groovy @@ -59,7 +59,7 @@ class GrpcRequestMessageHandlerTest extends IastModuleImplTestBase { handler.apply(reqCtx, target) then: - 1 * propagation.taintObjectDeeply(ctx, target, SourceTypes.GRPC_BODY, _ as Predicate>) + 1 * propagation.taintObjectDeeply(to, target, SourceTypes.GRPC_BODY, _ as Predicate>) } void 'the handler only takes into account protobuf v.#protobufVersion related messages'() { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextProviderTest.groovy similarity index 77% rename from dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextTest.groovy rename to dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextProviderTest.groovy index 43a129f2dd1..c1c06b6b9ef 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastGlobalContextProviderTest.groovy @@ -1,15 +1,15 @@ package com.datadog.iast -import com.datadog.iast.model.Range -import com.datadog.iast.taint.TaintedObjects +import datadog.trace.api.iast.taint.Range import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.test.util.DDSpecification import spock.lang.Shared -class IastGlobalContextTest extends DDSpecification { +class IastGlobalContextProviderTest extends DDSpecification { @Shared protected static final AgentTracer.TracerAPI ORIGINAL_TRACER = AgentTracer.get() @@ -25,11 +25,11 @@ class IastGlobalContextTest extends DDSpecification { activeSpan() >> span } - private IastGlobalContext.Provider provider + private IastGlobalContextProvider provider void setup() { AgentTracer.forceRegister(tracer) - provider = new IastGlobalContext.Provider() + provider = new IastGlobalContextProvider() } void cleanup() { @@ -42,12 +42,11 @@ class IastGlobalContextTest extends DDSpecification { reqCtx.getData(RequestContextSlot.IAST) >> iastReqCtx when: - def resolvedCtx = provider.resolve() + def taintedObjects = provider.resolveTaintedObjects() then: - resolvedCtx !== iastReqCtx - resolvedCtx === provider.globalContext - iastReqCtx.taintedObjects === resolvedCtx.taintedObjects + taintedObjects === iastReqCtx.taintedObjects + taintedObjects === provider.taintedObjects } void 'release does nothing to the tainted objects'() { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastModuleImplTestBase.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastModuleImplTestBase.groovy index 0d031c7d566..34227193e34 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastModuleImplTestBase.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastModuleImplTestBase.groovy @@ -6,6 +6,7 @@ import datadog.trace.api.Config import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot import datadog.trace.api.iast.IastContext +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.api.internal.TraceSegment import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer @@ -28,6 +29,8 @@ class IastModuleImplTestBase extends DDSpecification { protected IastRequestContext ctx + protected TaintedObjects to + protected TraceSegment traceSegment protected RequestContext reqCtx @@ -49,6 +52,7 @@ class IastModuleImplTestBase extends DDSpecification { void setup() { contextProvider = buildIastContextProvider() ctx = buildIastRequestContext() + to = ctx.taintedObjects traceSegment = buildTraceSegment() reqCtx = buildRequestContext() span = buildAgentSpan() @@ -73,7 +77,7 @@ class IastModuleImplTestBase extends DDSpecification { protected IastContext.Provider buildIastContextProvider() { return Config.get().getIastContextMode() == GLOBAL - ? new IastGlobalContext.Provider() + ? new IastGlobalContextProvider() : new IastRequestContext.Provider() } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextProviderTest.groovy similarity index 77% rename from dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextTest.groovy rename to dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextProviderTest.groovy index 5c03097b46e..004b09a2ee3 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastOptOutContextProviderTest.groovy @@ -1,15 +1,16 @@ package com.datadog.iast -import com.datadog.iast.model.Range -import com.datadog.iast.taint.TaintedObjects + +import datadog.trace.api.iast.taint.Range import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.test.util.DDSpecification import spock.lang.Shared -class IastOptOutContextTest extends DDSpecification { +class IastOptOutContextProviderTest extends DDSpecification { @Shared protected static final AgentTracer.TracerAPI ORIGINAL_TRACER = AgentTracer.get() @@ -25,11 +26,11 @@ class IastOptOutContextTest extends DDSpecification { activeSpan() >> span } - private IastOptOutContext.Provider provider + private IastOptOutContextProvider provider void setup() { AgentTracer.forceRegister(tracer) - provider = new IastOptOutContext.Provider() + provider = new IastOptOutContextProvider() } void cleanup() { @@ -42,12 +43,11 @@ class IastOptOutContextTest extends DDSpecification { reqCtx.getData(RequestContextSlot.IAST) >> iastReqCtx when: - def resolvedCtx = provider.resolve() + def to = provider.resolveTaintedObjects() then: - resolvedCtx !== iastReqCtx - resolvedCtx === provider.optOutContext - iastReqCtx.taintedObjects === resolvedCtx.taintedObjects + to === iastReqCtx.taintedObjects + to === TaintedObjects.NoOp.INSTANCE } void 'release does nothing to the tainted objects'() { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastRequestContextTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastRequestContextTest.groovy index 5d7fe0dde7c..95bf8eac6c6 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastRequestContextTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastRequestContextTest.groovy @@ -1,10 +1,10 @@ package com.datadog.iast -import com.datadog.iast.model.Range -import com.datadog.iast.taint.TaintedObjects +import datadog.trace.api.iast.taint.Range import datadog.trace.api.Config import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.test.util.DDSpecification @@ -43,27 +43,27 @@ class IastRequestContextTest extends DDSpecification { reqCtx.getData(RequestContextSlot.IAST) >> initialCtx when: - def resolved = provider.resolve() + def to = provider.resolveTaintedObjects() then: 1 * tracer.activeSpan() >> null - resolved == null + to == null when: - resolved = provider.resolve() + to = provider.resolveTaintedObjects() then: 1 * tracer.activeSpan() >> span 1 * span.getRequestContext() >> null - resolved == null + to == null when: - resolved = provider.resolve() + to = provider.resolveTaintedObjects() then: 1 * tracer.activeSpan() >> span 1 * span.getRequestContext() >> reqCtx - resolved === initialCtx + to === initialCtx.taintedObjects } void 'provider uses a pool of tainted objects'() { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastSystemTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastSystemTest.groovy index 71914a424a2..432e6df47d5 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastSystemTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastSystemTest.groovy @@ -112,7 +112,7 @@ class IastSystemTest extends DDSpecification { where: mode | providerClass - GLOBAL | IastGlobalContext.Provider + GLOBAL | IastGlobalContextProvider REQUEST | IastRequestContext.Provider } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/EvidenceTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/EvidenceTest.groovy index d21d573f6ec..a98c90f642c 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/EvidenceTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/EvidenceTest.groovy @@ -2,6 +2,8 @@ package com.datadog.iast.model import com.datadog.iast.model.json.VulnerabilityEncoding import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source import datadog.trace.test.util.DDSpecification import groovy.json.JsonSlurper @@ -42,7 +44,7 @@ class EvidenceTest extends DDSpecification { final Reference ref = new WeakReference<>(name) when: - final source = new Source(SourceTypes.REQUEST_PARAMETER_NAME, ref, "a random value") + final source = new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, ref, "a random value") final batch = vulnBatchForSource(source) then: @@ -54,14 +56,14 @@ class EvidenceTest extends DDSpecification { ref.clear() then: - source.getName() == Source.GARBAGE_COLLECTED_REF + source.getName() == SourceImpl.GARBAGE_COLLECTED_REF final parsedAfter = new JsonSlurper().parseText(VulnerabilityEncoding.toJson(batch)) parsedAfter["sources"][0]["name"] == name } private static VulnerabilityBatch vulnBatchForSource(final Source source) { final location = Location.forClassAndMethodAndLine(EvidenceTest.name, 'vulnBatchForSource', 69) - final evidence = new Evidence("test", [new Range(0, 4, source, NOT_MARKED)] as Range[]) + final evidence = new Evidence("test", [new RangeImpl(0, 4, source, NOT_MARKED)] as Range[]) final vuln = new Vulnerability(VulnerabilityType.INSECURE_COOKIE, location, evidence) final batch = new VulnerabilityBatch() batch.add(vuln) diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/RangeTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/RangeTest.groovy index 31035a94272..0f71a761532 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/RangeTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/RangeTest.groovy @@ -1,5 +1,7 @@ package com.datadog.iast.model +import com.datadog.iast.taint.Ranges + import static com.datadog.iast.model.VulnerabilityType.SQL_INJECTION import static com.datadog.iast.model.VulnerabilityType.XSS import datadog.trace.api.iast.SourceTypes @@ -16,8 +18,8 @@ class RangeTest extends DDSpecification { def 'shift'() { given: - final source = new Source(SourceTypes.NONE, null, null) - final orig = new Range(start, length, source, SQL_INJECTION_MARK) + final source = new SourceImpl(SourceTypes.NONE, null, null) + final orig = new RangeImpl(start, length, source, SQL_INJECTION_MARK) when: final result = orig.shift(shift) @@ -42,8 +44,8 @@ class RangeTest extends DDSpecification { def 'shift zero'() { given: - final source = new Source(SourceTypes.NONE, null, null) - final orig = new Range(0, 1, source, NOT_MARKED) + final source = new SourceImpl(SourceTypes.NONE, null, null) + final orig = new RangeImpl(0, 1, source, NOT_MARKED) when: final result = orig.shift(0) @@ -56,11 +58,11 @@ class RangeTest extends DDSpecification { void 'test getMarkedVulnerabilities #marks'() { given: - final source = new Source(SourceTypes.NONE, null, null) - final range = new Range(0, 1, source, marks) + final source = new SourceImpl(SourceTypes.NONE, null, null) + final range = new RangeImpl(0, 1, source, marks) when: - final vulnerabilities = range.getMarkedVulnerabilities() + final vulnerabilities = Ranges.getMarkedVulnerabilities(range) then: vulnerabilities == expected diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceEncodingTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceEncodingTest.groovy index 713596bd728..ef8877de300 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceEncodingTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceEncodingTest.groovy @@ -1,11 +1,14 @@ package com.datadog.iast.model.json import com.datadog.iast.model.Evidence -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import datadog.trace.api.config.IastConfig +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source + import static datadog.trace.api.iast.VulnerabilityMarks.XSS_MARK import datadog.trace.test.util.DDSpecification import org.skyscreamer.jsonassert.JSONAssert @@ -15,7 +18,7 @@ import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED class EvidenceEncodingTest extends DDSpecification { - private static final List SOURCES_SUITE = (0..2).collect { new Source((byte) it, "name$it", "value$it") } + private static final List SOURCES_SUITE = (0..2).collect { new SourceImpl((byte) it, "name$it", "value$it") } @Shared private JsonAdapter evidenceAdapter @@ -31,7 +34,6 @@ class EvidenceEncodingTest extends DDSpecification { AdapterFactory.Context.set(context) evidenceAdapter = new Moshi.Builder() - .add(new SourceTypeAdapter()) .add(new AdapterFactory()) .build() .adapter(Evidence) @@ -73,7 +75,7 @@ class EvidenceEncodingTest extends DDSpecification { } private static Range range(final int start, final int length, final Source source, final int mark) { - return new Range(start, length, source, mark) + return new RangeImpl(start, length, source, mark) } private static Source source(final int index) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceRedactionTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceRedactionTest.groovy index f52d8a5419f..4b363ffda11 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceRedactionTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/EvidenceRedactionTest.groovy @@ -1,7 +1,9 @@ package com.datadog.iast.model.json -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityBatch import com.datadog.iast.model.VulnerabilityType @@ -50,8 +52,7 @@ class EvidenceRedactionTest extends DDSpecification { void setupSpec() { final moshi = new Moshi.Builder() .add(new TestVulnerabilityAdapter()) - .add(new TestSourceIndexAdapter()) - .add(new TestSourceTypeStringAdapter()) + .add(new TestSourceAdapter()) .add(new TestRangeAdapter()) .build() sourcesParser = moshi.adapter(Types.newParameterizedType(List, Source)) @@ -248,22 +249,44 @@ class EvidenceRedactionTest extends DDSpecification { } } - static class TestSourceIndexAdapter { + static class TestSourceAdapter { + + private final TestSourceTypeStringAdapter sourceTypeAdapter = new TestSourceTypeStringAdapter() + @FromJson - @SourceIndex - Source fromJson(@Nonnull final JsonReader reader, final JsonAdapter adapter) throws IOException { - return adapter.fromJson(reader) + Source fromJson(@Nonnull final JsonReader reader) throws IOException { + reader.beginObject() + byte origin = -1 + String name = null + String value = null + while (reader.hasNext()) { + switch (reader.nextName()) { + case "origin": + origin = sourceTypeAdapter.fromJson(reader) + break + case "name": + name = reader.nextString() + break + case "value": + value = reader.nextString() + break + default: + reader.skipValue() + break + } + } + reader.endObject() + return new SourceImpl(origin, name, value) } @ToJson - void toJson(@Nonnull final JsonWriter writer, @Nonnull @SourceIndex final Source type) throws IOException { + void toJson(@Nonnull final JsonWriter writer, @Nonnull final Source type) throws IOException { throw new UnsupportedOperationException() } } static class TestSourceTypeStringAdapter { @FromJson - @SourceTypeString byte fromJson(@Nonnull final JsonReader reader) throws IOException { final value = reader.nextString() final count = SourceTypes.getDeclaredFields().findAll { @@ -276,11 +299,6 @@ class EvidenceRedactionTest extends DDSpecification { } return SourceTypes.NONE } - - @ToJson - void toJson(@Nonnull final JsonWriter writer, @Nonnull @SourceTypeString final byte type) throws IOException { - throw new UnsupportedOperationException() - } } static class TestRangeAdapter { @@ -312,7 +330,7 @@ class EvidenceRedactionTest extends DDSpecification { } } reader.endObject() - final range = new Range(start, length, source, mark) + final range = new RangeImpl(start, length, source, mark) return range.isValid() ? range : null } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/TaintedObjectEncodingTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/TaintedObjectEncodingTest.groovy index f4d69c168cf..e4564635bc6 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/TaintedObjectEncodingTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/TaintedObjectEncodingTest.groovy @@ -1,10 +1,12 @@ package com.datadog.iast.model.json -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source -import com.datadog.iast.taint.TaintedObject +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range +import com.datadog.iast.taint.TaintedObjectEntry import datadog.trace.api.config.IastConfig import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.TaintedObject import datadog.trace.test.util.DDSpecification import org.skyscreamer.jsonassert.JSONAssert @@ -84,9 +86,9 @@ class TaintedObjectEncodingTest extends DDSpecification { ]''', result, true) } - private TaintedObject taintedObject(final String value, final byte sourceType, final String sourceName, final String sourceValue) { - return new TaintedObject( + private static TaintedObject taintedObject(final String value, final byte sourceType, final String sourceName, final String sourceValue) { + return new TaintedObjectEntry( value, - [new Range(0, value.length(), new Source(sourceType, sourceName, sourceValue), NOT_MARKED)] as Range[]) + [new RangeImpl(0, value.length(), new SourceImpl(sourceType, sourceName, sourceValue), NOT_MARKED)] as Range[]) } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/VulnerabilityEncodingTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/VulnerabilityEncodingTest.groovy index b1103f3c94c..6db86647522 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/VulnerabilityEncodingTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/json/VulnerabilityEncodingTest.groovy @@ -2,13 +2,14 @@ package com.datadog.iast.model.json import com.datadog.iast.model.Evidence import com.datadog.iast.model.Location -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityBatch import com.datadog.iast.model.VulnerabilityType import datadog.trace.api.config.IastConfig import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.Range import datadog.trace.api.iast.telemetry.IastMetric import datadog.trace.api.iast.telemetry.IastMetricCollector import datadog.trace.bootstrap.instrumentation.api.AgentSpan @@ -133,7 +134,9 @@ class VulnerabilityEncodingTest extends DDSpecification { value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value"), NOT_MARKED)] as Range[]) + new Evidence("BAD", [ + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value"), NOT_MARKED) + ] as Range[]) )) when: @@ -179,8 +182,8 @@ class VulnerabilityEncodingTest extends DDSpecification { VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), new Evidence("BAD", [ - new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_NAME, "key", "value"), NOT_MARKED), - new Range(1, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value2"), NOT_MARKED) + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, "key", "value"), NOT_MARKED), + new RangeImpl(1, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value2"), NOT_MARKED) ] as Range[]) )) @@ -232,7 +235,7 @@ class VulnerabilityEncodingTest extends DDSpecification { value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.NONE, "key", "value"), NOT_MARKED)] as Range[]) + new Evidence("BAD", [new RangeImpl(0, 1, new SourceImpl(SourceTypes.NONE, "key", "value"), NOT_MARKED)] as Range[]) )) when: @@ -273,16 +276,16 @@ class VulnerabilityEncodingTest extends DDSpecification { final spanId = 123456 span.getSpanId() >> spanId final value = new VulnerabilityBatch() - final source = new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value") + final source = new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value") value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD1", [new Range(0, 1, source, NOT_MARKED)] as Range[]) + new Evidence("BAD1", [new RangeImpl(0, 1, source, NOT_MARKED)] as Range[]) )) value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD2", [new Range(0, 1, source, NOT_MARKED)] as Range[]) + new Evidence("BAD2", [new RangeImpl(0, 1, source, NOT_MARKED)] as Range[]) )) when: @@ -343,12 +346,16 @@ class VulnerabilityEncodingTest extends DDSpecification { value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key1", "value"), NOT_MARKED)] as Range[]) + new Evidence("BAD", [ + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key1", "value"), NOT_MARKED) + ] as Range[]) )) value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED)] as Range[]) + new Evidence("BAD", [ + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED) + ] as Range[]) )) when: @@ -449,12 +456,16 @@ class VulnerabilityEncodingTest extends DDSpecification { value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence(generateLargeString(), [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key1", "value"), NOT_MARKED)] as Range[]) + new Evidence(generateLargeString(), [ + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key1", "value"), NOT_MARKED) + ] as Range[]) )) value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), - new Evidence(generateLargeString(), [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED)] as Range[]) + new Evidence(generateLargeString(), [ + new RangeImpl(0, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED) + ] as Range[]) )) when: @@ -551,7 +562,7 @@ class VulnerabilityEncodingTest extends DDSpecification { VulnerabilityType.WEAK_HASH, Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), new Evidence(largeString, [ - new Range(0, largeString.length(), new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", largeString), NOT_MARKED) + new RangeImpl(0, largeString.length(), new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", largeString), NOT_MARKED) ] as Range[]) ) } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/CodecModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/CodecModuleTest.groovy index ed15a3fc63f..6cb7309ff9c 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/CodecModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/CodecModuleTest.groovy @@ -1,10 +1,10 @@ package com.datadog.iast.propagation import com.datadog.iast.IastModuleImplTestBase -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range import com.datadog.iast.taint.Ranges -import com.datadog.iast.taint.TaintedObjects import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.VulnerabilityMarks import datadog.trace.api.iast.propagation.CodecModule @@ -34,22 +34,6 @@ class CodecModuleTest extends IastModuleImplTestBase { } } - void '#method null'() { - when: - module.&"$method".call(args.toArray()) - - then: - 0 * _ - - where: - method | args - 'onUrlDecode' | ['test', 'utf-8', null] - 'onStringGetBytes' | ['test', 'utf-8', null] - 'onStringFromBytes' | ['test'.bytes, 0, 2, 'utf-8', null] - 'onBase64Encode' | ['test'.bytes, null] - 'onBase64Decode' | ['test'.bytes, null] - } - void '#method no context'() { when: module.&"$method".call(args.toArray()) @@ -276,10 +260,10 @@ class CodecModuleTest extends IastModuleImplTestBase { final charset = StandardCharsets.UTF_8 final string = "Hello World!" final bytes = string.getBytes(charset) // 1 byte pe char - final TaintedObjects to = ctx.taintedObjects + final to = ctx.taintedObjects final ranges = [ - new Range(0, 5, new Source((byte) 0, 'name1', 'Hello'), VulnerabilityMarks.NOT_MARKED), - new Range(6, 6, new Source((byte) 1, 'name2', 'World!'), VulnerabilityMarks.NOT_MARKED) + new RangeImpl(0, 5, new SourceImpl((byte) 0, 'name1', 'Hello'), VulnerabilityMarks.NOT_MARKED), + new RangeImpl(6, 6, new SourceImpl((byte) 1, 'name2', 'World!'), VulnerabilityMarks.NOT_MARKED) ] to.taint(bytes, ranges as Range[]) diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/PropagationModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/PropagationModuleTest.groovy index 40788ecdc3b..cd07bbb0dab 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/PropagationModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/PropagationModuleTest.groovy @@ -1,16 +1,18 @@ package com.datadog.iast.propagation import com.datadog.iast.IastModuleImplTestBase -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import com.datadog.iast.taint.Ranges - -import com.datadog.iast.taint.TaintedObject +import com.datadog.iast.taint.TaintedObjectEntry import datadog.trace.api.Config import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.VulnerabilityMarks import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source +import datadog.trace.api.iast.taint.TaintedObject import datadog.trace.bootstrap.instrumentation.api.AgentTracer import org.junit.Assume import spock.lang.Shared @@ -39,60 +41,50 @@ class PropagationModuleTest extends IastModuleImplTestBase { } } - void '#method(#argTypes) not taintable'() { - when: 'there is no context by default' + void '#method(#argTypes) with null values'() { + when: 'null tainted objects' + args.add(0, null) module.&"$method".call(args.toArray()) then: 'no mock calls should happen' 0 * _ - when: 'there is a context' - args.add(0, ctx) + when: 'there are tainted objects but the value is null' + args.set(0, to) module.&"$method".call(args.toArray()) - then: 'no mock calls should happen' + then: 'no mock calls should happen\'' 0 * _ where: method | args 'taintObject' | [null, SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintString' | [null, SourceTypes.REQUEST_PARAMETER_VALUE] 'taintObject' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintString' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] 'taintObject' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintString' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] 'taintObjectRange' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 0, 10] - 'taintStringRange' | [null, SourceTypes.REQUEST_PARAMETER_VALUE, 0, 10] 'taintObjectIfTainted' | [null, 'test'] - 'taintStringIfTainted' | [null, 'test'] 'taintObjectIfTainted' | [date(), null] - 'taintStringIfTainted' | ['test', null] + 'taintObjectIfTainted' | ['test', null] 'taintObjectIfTainted' | [null, 'test', false, NOT_MARKED] - 'taintStringIfTainted' | [null, 'test', false, NOT_MARKED] 'taintObjectIfTainted' | [date(), null, false, NOT_MARKED] - 'taintStringIfTainted' | ['test', null, false, NOT_MARKED] + 'taintObjectIfTainted' | ['test', null, false, NOT_MARKED] 'taintObjectIfRangeTainted' | [null, 'test', 0, 4, false, NOT_MARKED] - 'taintStringIfRangeTainted' | [null, 'test', 0, 4, false, NOT_MARKED] 'taintObjectIfRangeTainted' | [date(), null, 0, 4, false, NOT_MARKED] - 'taintStringIfRangeTainted' | ['test', null, 0, 4, false, NOT_MARKED] + 'taintObjectIfRangeTainted' | ['test', null, 0, 4, false, NOT_MARKED] 'taintObjectIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintStringIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE] 'taintObjectIfTainted' | [date(), null, SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintStringIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE] + 'taintObjectIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE] 'taintObjectIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintStringIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] 'taintObjectIfTainted' | [date(), null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintStringIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] + 'taintObjectIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] 'taintObjectIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintStringIfTainted' | [null, 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] 'taintObjectIfTainted' | [date(), null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintStringIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] + 'taintObjectIfTainted' | ['test', null, SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] 'taintObjectIfAnyTainted' | [null, ['test'] as Object[]] - 'taintStringIfAnyTainted' | [null, ['test'] as Object[]] 'taintObjectIfAnyTainted' | [date(), null] - 'taintStringIfAnyTainted' | ['test', null] + 'taintObjectIfAnyTainted' | ['test', null] 'taintObjectIfAnyTainted' | [date(), [] as Object[]] - 'taintStringIfAnyTainted' | ['test', [] as Object[]] + 'taintObjectIfAnyTainted' | ['test', [] as Object[]] 'taintObjectDeeply' | [ null, SourceTypes.REQUEST_PARAMETER_VALUE, @@ -105,49 +97,6 @@ class PropagationModuleTest extends IastModuleImplTestBase { argTypes = args*.class.name } - void '#method without span'() { - when: - module.&"$method".call(args.toArray()) - - then: - 1 * tracer.activeSpan() >> null - 0 * _ - - where: - method | args - 'taintObject' | [date(), SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintString' | ['test', SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintObject' | [date(), SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintString' | ['test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintObject' | [date(), SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintString' | ['test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintObjectRange' | [date(), SourceTypes.REQUEST_PARAMETER_VALUE, 0, 10] - 'taintStringRange' | ['test', SourceTypes.REQUEST_PARAMETER_VALUE, 0, 10] - 'taintObjectIfTainted' | [date(), 'test'] - 'taintStringIfTainted' | ['test', 'test'] - 'taintObjectIfRangeTainted' | [date(), 'test', 0, 4, false, NOT_MARKED] - 'taintStringIfRangeTainted' | ['test', 'test', 0, 4, false, NOT_MARKED] - 'taintObjectIfTainted' | [date(), 'test', false, NOT_MARKED] - 'taintStringIfTainted' | ['test', 'test', false, NOT_MARKED] - 'taintObjectIfTainted' | [date(), 'test', SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintStringIfTainted' | ['test', 'test', SourceTypes.REQUEST_PARAMETER_VALUE] - 'taintObjectIfTainted' | [date(), 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintStringIfTainted' | ['test', 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name'] - 'taintObjectIfTainted' | [date(), 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintStringIfTainted' | ['test', 'test', SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value'] - 'taintObjectIfAnyTainted' | [date(), ['test']] - 'taintStringIfAnyTainted' | ['test', ['test']] - 'taintObjectDeeply' | [ - 'test', - SourceTypes.REQUEST_PARAMETER_VALUE, - { - true - } - ] - 'findSource' | ['test'] - 'isTainted' | ['test'] - } - void 'test taint'() { given: final value = (target instanceof CharSequence) ? target.toString() : null @@ -155,7 +104,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { final ranges = Ranges.forObject(source) when: - module."$method"(target, source.origin, source.name, source.value) + module."$method"(to, target, source.origin, source.name, source.value) then: final tainted = getTaintedObject(target) @@ -167,7 +116,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { where: method | target | shouldTaint - 'taintString' | string('string') | true + 'taintObject' | string('string') | true 'taintObject' | stringBuilder('stringBuilder') | true 'taintObject' | date() | true 'taintObject' | taintable() | true @@ -176,11 +125,11 @@ class PropagationModuleTest extends IastModuleImplTestBase { void 'test taint with range'() { given: final value = (target instanceof CharSequence) ? target.toString() : null - final source = new Source(SourceTypes.REQUEST_PARAMETER_VALUE, null, value) - final ranges = [new Range(start, length, source, NOT_MARKED)] as Range[] + final source = new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, null, value) + final ranges = [new RangeImpl(start, length, source, NOT_MARKED)] as Range[] when: - module."$method"(target, source.origin, start, length) + module."$method"(to, target, source.origin, start, length) then: final tainted = getTaintedObject(target) @@ -188,7 +137,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { where: method | target | start | length - 'taintStringRange' | string('string') | 0 | 2 + 'taintObjectRange' | string('string') | 0 | 2 'taintObjectRange' | stringBuilder('stringBuilder') | 0 | 2 'taintObjectRange' | date() | 0 | 2 'taintObjectRange' | taintable() | 0 | 2 @@ -199,17 +148,17 @@ class PropagationModuleTest extends IastModuleImplTestBase { def (type, target, input) = suite final method = "taint${type}IfTainted" final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] when: 'input is not tainted' - module."$method"(target, input, true, NOT_MARKED) + module."$method"(to, target, input, true, NOT_MARKED) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, input, true, NOT_MARKED) + module."$method"(to, target, input, true, NOT_MARKED) then: final tainted = getTaintedObject(target) @@ -229,17 +178,17 @@ class PropagationModuleTest extends IastModuleImplTestBase { def (type, target, input) = suite final method = "taint${type}IfRangeTainted" final source = taintedSource() - final ranges = [new Range(0, 2, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 2, source, NOT_MARKED)] as Range[] when: 'input is not tainted' - module."$method"(target, input, 0, 2, false, NOT_MARKED) + module."$method"(to, target, input, 0, 2, false, NOT_MARKED) then: assert getTaintedObject(target) == null when: 'input tainted but range does not overlap' final firstTaintedForm = taintObject(input, ranges) - module."$method"(target, input, 4, 3, false, NOT_MARKED) + module."$method"(to, target, input, 4, 3, false, NOT_MARKED) then: final firstTainted = getTaintedObject(target) @@ -253,7 +202,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { when: 'input is tainted and range overlaps' ctx.taintedObjects.clear() final secondTaintedFrom = taintObject(input, ranges) - module."$method"(target, input, 0, 2, false, NOT_MARKED) + module."$method"(to, target, input, 0, 2, false, NOT_MARKED) then: final secondTainted = getTaintedObject(target) @@ -274,18 +223,18 @@ class PropagationModuleTest extends IastModuleImplTestBase { Assume.assumeFalse(target instanceof Taintable) // taintable does not support multiple ranges or marks final method = "taint${type}IfTainted" final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] final mark = VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK when: 'input is not tainted' - module."$method"(target, input, true, mark) + module."$method"(to, target, input, true, mark) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, input, true, mark) + module."$method"(to, target, input, true, mark) then: final tainted = getTaintedObject(target) @@ -300,17 +249,17 @@ class PropagationModuleTest extends IastModuleImplTestBase { def (type, target, input) = suite final method = "taint${type}IfTainted" final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] when: 'input is not tainted' - module."$method"(target, input, false, NOT_MARKED) + module."$method"(to, target, input, false, NOT_MARKED) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, input, false, NOT_MARKED) + module."$method"(to, target, input, false, NOT_MARKED) then: final tainted = getTaintedObject(target) @@ -326,18 +275,18 @@ class PropagationModuleTest extends IastModuleImplTestBase { Assume.assumeFalse(target instanceof Taintable) // taintable does not support marks final method = "taint${type}IfTainted" final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] final mark = VulnerabilityMarks.LDAP_INJECTION_MARK when: 'input is not tainted' - module."$method"(target, input, false, mark) + module."$method"(to, target, input, false, mark) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, input, false, mark) + module."$method"(to, target, input, false, mark) then: final tainted = getTaintedObject(target) @@ -353,17 +302,17 @@ class PropagationModuleTest extends IastModuleImplTestBase { final method = "taint${type}IfAnyTainted" final inputs = ['test', input].toArray() final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] when: 'input is not tainted' - module."$method"(target, inputs, true, NOT_MARKED) + module."$method"(to, target, inputs, true, NOT_MARKED) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, inputs, true, NOT_MARKED) + module."$method"(to, target, inputs, true, NOT_MARKED) then: final tainted = getTaintedObject(target) @@ -385,18 +334,18 @@ class PropagationModuleTest extends IastModuleImplTestBase { final method = "taint${type}IfAnyTainted" final inputs = ['test', input].toArray() final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] final mark = VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK when: 'input is not tainted' - module."$method"(target, inputs, true, mark) + module."$method"(to, target, inputs, true, mark) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, inputs, true, mark) + module."$method"(to, target, inputs, true, mark) then: final tainted = getTaintedObject(target) @@ -412,17 +361,17 @@ class PropagationModuleTest extends IastModuleImplTestBase { final method = "taint${type}IfAnyTainted" final inputs = ['test', input].toArray() final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] when: 'input is not tainted' - module."$method"(target, inputs, false, NOT_MARKED) + module."$method"(to, target, inputs, false, NOT_MARKED) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, inputs, false, NOT_MARKED) + module."$method"(to, target, inputs, false, NOT_MARKED) then: final tainted = getTaintedObject(target) @@ -439,18 +388,18 @@ class PropagationModuleTest extends IastModuleImplTestBase { final method = "taint${type}IfAnyTainted" final inputs = ['test', input].toArray() final source = taintedSource() - final ranges = [new Range(0, 1, source, NOT_MARKED), new Range(1, 1, source, NOT_MARKED)] as Range[] + final ranges = [new RangeImpl(0, 1, source, NOT_MARKED), new RangeImpl(1, 1, source, NOT_MARKED)] as Range[] final mark = VulnerabilityMarks.LDAP_INJECTION_MARK when: 'input is not tainted' - module."$method"(target, inputs, false, mark) + module."$method"(to, target, inputs, false, mark) then: assert getTaintedObject(target) == null when: 'input is tainted' final taintedFrom = taintObject(input, ranges) - module."$method"(target, inputs, false, mark) + module."$method"(to, target, inputs, false, mark) then: final tainted = getTaintedObject(target) @@ -465,7 +414,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { final target = [Hello: " World!", Age: 25] when: - module.taintObjectDeeply(target, SourceTypes.GRPC_BODY, { true }) + module.taintObjectDeeply(to, target, SourceTypes.GRPC_BODY, { true }) then: final taintedObjects = ctx.taintedObjects @@ -481,7 +430,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { final target = stringBuilder('taint me') when: - module.taintObjectDeeply(target, SourceTypes.GRPC_BODY, { true }) + module.taintObjectDeeply(to, target, SourceTypes.GRPC_BODY, { true }) then: final taintedObjects = ctx.taintedObjects @@ -500,13 +449,13 @@ class PropagationModuleTest extends IastModuleImplTestBase { } when: - final tainted = module.isTainted(target) + final tainted = module.isTainted(to, target) then: tainted == (source != null) when: - final foundSource = module.findSource(target) + final foundSource = module.findSource(to, target) then: foundSource == source @@ -526,13 +475,12 @@ class PropagationModuleTest extends IastModuleImplTestBase { void 'test source names over threshold'() { given: assert target.length() > maxValueLength - final method = target instanceof String ? 'taintString' : 'taintObject' when: - module."$method"(target, SourceTypes.REQUEST_PARAMETER_VALUE) + module.taintObject(to, target, SourceTypes.REQUEST_PARAMETER_VALUE) then: - final tainted = ctx.getTaintedObjects().get(target) + final tainted = to.get(target) tainted != null final sourceValue = tainted.ranges.first().source.value if (resize) { @@ -548,14 +496,11 @@ class PropagationModuleTest extends IastModuleImplTestBase { } void 'test that source names/values should not make a strong reference over the value'() { - given: - final method = toTaint instanceof String ? 'taintString' : 'taintObject' - when: - module."$method"(toTaint, SourceTypes.REQUEST_PARAMETER_NAME, name, value) + module.taintObject(to, toTaint, SourceTypes.REQUEST_PARAMETER_NAME, name, value) then: - final tainted = ctx.getTaintedObjects().get(toTaint) + final tainted = to.get(toTaint) final source = tainted.ranges.first().source final sourceName = source.@name final sourceValue = source.@value @@ -573,7 +518,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { assert sourceValue == value.toString() break default: - assert sourceValue === Source.PROPAGATION_PLACEHOLDER + assert sourceValue === SourceImpl.PROPAGATION_PLACEHOLDER break } if (name === value) { @@ -599,19 +544,19 @@ class PropagationModuleTest extends IastModuleImplTestBase { final baos = toTaint.bytes when: 'tainting a non char sequence object' - module.taintObject(baos, SourceTypes.KAFKA_MESSAGE_KEY) + module.taintObject(to, baos, SourceTypes.KAFKA_MESSAGE_KEY) then: with(ctx.taintedObjects.get(baos)) { assert ranges.length == 1 - final source = ranges.first().source + final source = ranges.first().source as SourceImpl assert source.origin == SourceTypes.KAFKA_MESSAGE_KEY - assert source.@value === Source.PROPAGATION_PLACEHOLDER + assert source.@value === SourceImpl.PROPAGATION_PLACEHOLDER assert source.value == null } when: 'the object is propagated' - module.taintStringIfTainted(toTaint, baos) + module.taintObjectIfTainted(to, toTaint, baos) then: with(ctx.taintedObjects.get(toTaint)) { @@ -624,10 +569,10 @@ class PropagationModuleTest extends IastModuleImplTestBase { private List> taintIfSuite() { return [ - Tuple.tuple("String", string('string'), string('string')), - Tuple.tuple("String", string('string'), stringBuilder('stringBuilder')), - Tuple.tuple("String", string('string'), date()), - Tuple.tuple("String", string('string'), taintable()), + Tuple.tuple("Object", string('string'), string('string')), + Tuple.tuple("Object", string('string'), stringBuilder('stringBuilder')), + Tuple.tuple("Object", string('string'), date()), + Tuple.tuple("Object", string('string'), taintable()), Tuple.tuple("Object", stringBuilder('stringBuilder'), string('string')), Tuple.tuple("Object", stringBuilder('stringBuilder'), stringBuilder('stringBuilder')), Tuple.tuple("Object", stringBuilder('stringBuilder'), date()), @@ -646,7 +591,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { private TaintedObject getTaintedObject(final Object target) { if (target instanceof Taintable) { final source = (target as Taintable).$$DD$getSource() as Source - return source == null ? null : new TaintedObject(target, Ranges.forObject(source)) + return source == null ? null : new TaintedObjectEntry(target, Ranges.forObject(source)) } return ctx.getTaintedObjects().get(target) } @@ -704,7 +649,7 @@ class PropagationModuleTest extends IastModuleImplTestBase { } private Source taintedSource(String value = 'value') { - return new Source(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value) + return new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value) } private static void assertTainted(final TaintedObject tainted, final Range[] ranges, final int mark = NOT_MARKED) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/StringModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/StringModuleTest.groovy index 99b17559b4b..5eb7be55a4a 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/StringModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/propagation/StringModuleTest.groovy @@ -1,13 +1,15 @@ package com.datadog.iast.propagation import com.datadog.iast.IastModuleImplTestBase -import com.datadog.iast.model.Source -import com.datadog.iast.taint.TaintedObjects +import com.datadog.iast.model.SourceImpl import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.StringModule +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import groovy.transform.CompileDynamic @@ -480,7 +482,7 @@ class StringModuleTest extends IastModuleImplTestBase { if (shouldBeTainted) { assert to != null assert to.get() == result - assert taintFormat(to.get() as String, to.getRanges()) == expected + assert taintFormat(to.get() as String, to.ranges) == expected } else { assert to == null } @@ -757,7 +759,7 @@ class StringModuleTest extends IastModuleImplTestBase { then: self.size() == lengthSelf result.size() == lengthResult - com.datadog.iast.model.Range[] ranges = taintedObject.getRanges() + Range[] ranges = taintedObject.getRanges() taintFormat(result, ranges) == expected ranges.size() == expectedRanges.size() @@ -797,7 +799,7 @@ class StringModuleTest extends IastModuleImplTestBase { then: self.size() == lengthSelf result.size() == lengthResult - com.datadog.iast.model.Range[] ranges = taintedObject.getRanges() + Range[] ranges = taintedObject.getRanges() taintFormat(result, ranges) == expected ranges.size() == expectedRanges.size() @@ -1383,7 +1385,7 @@ class StringModuleTest extends IastModuleImplTestBase { } private static Source taintedSource(String value = 'value') { - return new Source(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value) + return new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value) } private static Taintable taintable(TaintedObjects tos, Source source = null) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/AbstractSinkModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/AbstractSinkModuleTest.groovy index f405b9f33ea..297a68d15e5 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/AbstractSinkModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/AbstractSinkModuleTest.groovy @@ -1,10 +1,11 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import com.datadog.iast.overhead.Operations import com.datadog.iast.propagation.PropagationModuleImpl import com.datadog.iast.taint.Ranges +import datadog.trace.api.iast.taint.Source import datadog.trace.api.iast.Taintable import java.lang.ref.WeakReference @@ -58,10 +59,11 @@ class AbstractSinkModuleTest extends IastModuleImplTestBase { final sink = new SinkModuleBase(dependencies) {} final propagation = new PropagationModuleImpl() final input = new String(source.value) - ctx.getTaintedObjects().taint(input, Ranges.forCharSequence(input, source)) + final to = ctx.taintedObjects + to.taint(input, Ranges.forCharSequence(input, source)) when: - propagation.taintObjectIfTainted(toReport, input) + propagation.taintObjectIfTainted(to, toReport, input) final evidence = sink.checkInjection(SSRF, toReport) then: @@ -77,10 +79,10 @@ class AbstractSinkModuleTest extends IastModuleImplTestBase { where: source | toReport | matches - new Source(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URL('https://datadog.com/index.html') | true - new Source(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://datadog.com/index.html') | true - new Source(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://dAtAdOg.com/index.html') | false - new Source(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://dAtAdOg.com/index.html') | false + new SourceImpl(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URL('https://datadog.com/index.html') | true + new SourceImpl(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://datadog.com/index.html') | true + new SourceImpl(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://dAtAdOg.com/index.html') | false + new SourceImpl(REQUEST_PARAMETER_VALUE, 'url', 'datadog.com') | new URI('https://dAtAdOg.com/index.html') | false } void 'test reporting with taintables'() { @@ -88,7 +90,7 @@ class AbstractSinkModuleTest extends IastModuleImplTestBase { final sink = new SinkModuleBase(dependencies) {} final value = 'datadog.com' final valueRef = new WeakReference<>(value) - final source = new Source(REQUEST_PARAMETER_VALUE, 'url', valueRef) + final source = new SourceImpl(REQUEST_PARAMETER_VALUE, 'url', valueRef) and: final taintable = new MockTaintable(source: source) diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HeaderInjectionModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HeaderInjectionModuleTest.groovy index 24970e82f5e..05eeb3daa9c 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HeaderInjectionModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HeaderInjectionModuleTest.groovy @@ -2,8 +2,9 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import datadog.trace.api.iast.VulnerabilityMarks @@ -154,7 +155,7 @@ class HeaderInjectionModuleTest extends IastModuleImplTestBase { } private static Range source(byte origin, String name, String value) { - return new Range(0, value.length(), new Source(origin, name, value), NOT_MARKED) + return new RangeImpl(0, value.length(), new SourceImpl(origin, name, value), NOT_MARKED) } private String mapTainted(final String value, final int mark) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HttpResponseHeaderModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HttpResponseHeaderModuleTest.groovy index c1a35d10c65..e380d5f963b 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HttpResponseHeaderModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HttpResponseHeaderModuleTest.groovy @@ -6,10 +6,10 @@ import com.datadog.iast.Reporter import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.overhead.Operations -import com.datadog.iast.taint.TaintedObjects import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.sink.HeaderInjectionModule import datadog.trace.api.iast.sink.UnvalidatedRedirectModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.api.iast.util.Cookie import datadog.trace.bootstrap.instrumentation.api.AgentTracer diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/SsrfModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/SsrfModuleTest.groovy index f8986c35b2c..13a9787cee1 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/SsrfModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/SsrfModuleTest.groovy @@ -2,8 +2,9 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.taint.Ranges @@ -65,8 +66,8 @@ class SsrfModuleTest extends IastModuleImplTestBase { given: final value = new URL('http://test.com') final Range[] ranges = [ - new Range(0, 2, new Source(SourceTypes.REQUEST_HEADER_VALUE, 'name1', 'value'), VulnerabilityMarks.SSRF_MARK), - new Range(4, 1, new Source(SourceTypes.REQUEST_PARAMETER_NAME, 'name2', 'value'), VulnerabilityMarks.SSRF_MARK) + new RangeImpl(0, 2, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'name1', 'value'), VulnerabilityMarks.SSRF_MARK), + new RangeImpl(4, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, 'name2', 'value'), VulnerabilityMarks.SSRF_MARK) ] ctx.getTaintedObjects().taint(value, ranges) @@ -78,6 +79,6 @@ class SsrfModuleTest extends IastModuleImplTestBase { } private taint(final Object value) { - ctx.getTaintedObjects().taint(value, Ranges.forObject(new Source(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value.toString()))) + ctx.getTaintedObjects().taint(value, Ranges.forObject(new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', value.toString()))) } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/TrustBoundaryViolationModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/TrustBoundaryViolationModuleTest.groovy index 93ed876a6dd..6429540c176 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/TrustBoundaryViolationModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/TrustBoundaryViolationModuleTest.groovy @@ -2,7 +2,7 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.taint.Ranges @@ -47,7 +47,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { given: Vulnerability savedVul final name = "name" - ctx.getTaintedObjects().taint(name, Ranges.forCharSequence(name, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(name, Ranges.forCharSequence(name, new SourceImpl(SourceTypes.NONE, null, null))) when: module.onSessionValue(name, "value") @@ -62,7 +62,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { Vulnerability savedVul final name = "name" final badValue = "theValue" - ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new SourceImpl(SourceTypes.NONE, null, null))) when: module.onSessionValue(name, badValue) @@ -78,7 +78,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { Vulnerability savedVul final name = "name" final badValue = "badValue" - ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new SourceImpl(SourceTypes.NONE, null, null))) final values = ["A", "B", badValue] when: @@ -94,7 +94,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { Vulnerability savedVul final name = "name" final badValue = "badValue" - ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new SourceImpl(SourceTypes.NONE, null, null))) final values = new String[3] values[0] = "A" values[1] = "B" @@ -113,7 +113,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { Vulnerability savedVul final name = "name" final badValue = "badValue" - ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new SourceImpl(SourceTypes.NONE, null, null))) final values = new LinkedHashMap() values.put("A", "A") values.put("B", "B") @@ -131,7 +131,7 @@ class TrustBoundaryViolationModuleTest extends IastModuleImplTestBase { given: final name = "name" final badValue = "badValue" - ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new Source(SourceTypes.NONE, null, null))) + ctx.getTaintedObjects().taint(badValue, Ranges.forCharSequence(badValue, new SourceImpl(SourceTypes.NONE, null, null))) when: module.onSessionValue(name, new VisitableClass(name: badValue)) diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UntrustedDeserializationModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UntrustedDeserializationModuleTest.groovy index afd141168b1..0c16a3a5487 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UntrustedDeserializationModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UntrustedDeserializationModuleTest.groovy @@ -2,7 +2,7 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.taint.Ranges @@ -49,6 +49,6 @@ class UntrustedDeserializationModuleTest extends IastModuleImplTestBase { } private void taint(final Object value) { - ctx.getTaintedObjects().taint(value, Ranges.forObject(new Source(SourceTypes.REQUEST_BODY, 'name', value.toString()))) + ctx.getTaintedObjects().taint(value, Ranges.forObject(new SourceImpl(SourceTypes.REQUEST_BODY, 'name', value.toString()))) } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UnvalidatedRedirectModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UnvalidatedRedirectModuleTest.groovy index fd9690f9319..696a30908d1 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UnvalidatedRedirectModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/UnvalidatedRedirectModuleTest.groovy @@ -2,8 +2,9 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import datadog.trace.api.iast.taint.Range +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.taint.Ranges @@ -52,7 +53,7 @@ class UnvalidatedRedirectModuleTest extends IastModuleImplTestBase { void 'iast module detects URI redirect (#value)'(final URI value, final String expected) { setup: - ctx.taintedObjects.taint(value, Ranges.forObject(new Source(SourceTypes.NONE, null, null))) + ctx.taintedObjects.taint(value, Ranges.forObject(new SourceImpl(SourceTypes.NONE, null, null))) when: module.onURIRedirect(value) @@ -114,8 +115,8 @@ class UnvalidatedRedirectModuleTest extends IastModuleImplTestBase { void 'If all ranges from tainted element have referer header as source, is not an unvalidated redirect'() { setup: def value = 'test01' - def refererSource = new Source(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value') - Range[] ranges = [new Range(0, 2, refererSource, NOT_MARKED), new Range(4, 1, refererSource, NOT_MARKED)] + def refererSource = new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value') + Range[] ranges = [new RangeImpl(0, 2, refererSource, NOT_MARKED), new RangeImpl(4, 1, refererSource, NOT_MARKED)] ctx.getTaintedObjects().taint(value, ranges) when: @@ -138,16 +139,16 @@ class UnvalidatedRedirectModuleTest extends IastModuleImplTestBase { where: value | ranges 'test01' | [ - new Range(0, 2, new Source(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), NOT_MARKED), - new Range(4, 1, new Source(SourceTypes.REQUEST_HEADER_VALUE, 'other', 'value'), NOT_MARKED) + new RangeImpl(0, 2, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), NOT_MARKED), + new RangeImpl(4, 1, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'other', 'value'), NOT_MARKED) ] 'test02' | [ - new Range(0, 2, new Source(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), NOT_MARKED), - new Range(4, 1, new Source(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), NOT_MARKED) + new RangeImpl(0, 2, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), NOT_MARKED), + new RangeImpl(4, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), NOT_MARKED) ] 'test03' | [ - new Range(0, 2, new Source(SourceTypes.REQUEST_HEADER_VALUE, null, null), NOT_MARKED), - new Range(4, 1, new Source(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), NOT_MARKED) + new RangeImpl(0, 2, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, null, null), NOT_MARKED), + new RangeImpl(4, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), NOT_MARKED) ] } @@ -155,8 +156,8 @@ class UnvalidatedRedirectModuleTest extends IastModuleImplTestBase { given: final value = 'test' final Range[] ranges = [ - new Range(0, 2, new Source(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK), - new Range(4, 1, new Source(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK) + new RangeImpl(0, 2, new SourceImpl(SourceTypes.REQUEST_HEADER_VALUE, 'referer', 'value'), VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK), + new RangeImpl(4, 1, new SourceImpl(SourceTypes.REQUEST_PARAMETER_NAME, 'referer', 'value'), VulnerabilityMarks.UNVALIDATED_REDIRECT_MARK) ] ctx.getTaintedObjects().taint(value, ranges) diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/XssModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/XssModuleTest.groovy index 19006a4ee60..1b33431b8a1 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/XssModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/XssModuleTest.groovy @@ -2,7 +2,7 @@ package com.datadog.iast.sink import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.Reporter -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import com.datadog.iast.model.Vulnerability import com.datadog.iast.model.VulnerabilityType import com.datadog.iast.taint.Ranges @@ -53,7 +53,7 @@ class XssModuleTest extends IastModuleImplTestBase { void 'module detects char[] XSS'() { setup: if (tainted) { - ctx.taintedObjects.taint(buf, Ranges.forObject(new Source(SourceTypes.NONE, '', ''), mark)) + ctx.taintedObjects.taint(buf, Ranges.forObject(new SourceImpl(SourceTypes.NONE, '', ''), mark)) } when: @@ -95,16 +95,7 @@ class XssModuleTest extends IastModuleImplTestBase { where: format | array | mark | expected - null | null | NOT_MARKED | null - '/var' | ['a', 'b'] | NOT_MARKED | null '/==>var<==' | ['a', 'b'] | NOT_MARKED | "/==>var<== a b" - null | ['a', 'b'] | NOT_MARKED | null - '/var' | ['==>a<==', null] | NOT_MARKED | "/var ==>a<==" - '/var' | ['==>a<==', 'b'] | NOT_MARKED | "/var ==>a<== b" - '/var' | ['==>a<==', '==>b<=='] | NOT_MARKED | "/var ==>a<== ==>b<==" - '/==>var<==' | ['==>a<==', '==>b<=='] | NOT_MARKED | "/==>var<== ==>a<== ==>b<==" - '/==>var<==' | ['a', 'b'] | VulnerabilityMarks.XSS_MARK | null - '/==>var<==' | ['a', 'b'] | VulnerabilityMarks.SQL_INJECTION_MARK | "/==>var<== a b" } void 'module detects Charsequence XSS with file and line'() { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/RangesTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/RangesTest.groovy index 7d39fa1cad6..eacd39a7c09 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/RangesTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/RangesTest.groovy @@ -1,7 +1,8 @@ package com.datadog.iast.taint -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range import com.datadog.iast.model.VulnerabilityType import datadog.trace.api.Config import datadog.trace.api.iast.SourceTypes @@ -23,7 +24,7 @@ class RangesTest extends DDSpecification { void 'forString'() { given: - final source = new Source(SourceTypes.NONE, null, null) + final source = new SourceImpl(SourceTypes.NONE, null, null) when: final result = Ranges.forCharSequence(s, source, VulnerabilityMarks.SQL_INJECTION_MARK) @@ -76,7 +77,7 @@ class RangesTest extends DDSpecification { void 'forObject'() { given: - final source = new Source(SourceTypes.NONE, null, null) + final source = new SourceImpl(SourceTypes.NONE, null, null) when: final result = Ranges.forObject(source, VulnerabilityMarks.SQL_INJECTION_MARK) @@ -92,10 +93,10 @@ class RangesTest extends DDSpecification { void 'highestPriorityRange'() { given: - final range1 = new Range(0, 1, null, NOT_MARKED) - final range2 = new Range(0, 1, null, VulnerabilityMarks.SQL_INJECTION_MARK) - final range3 = new Range(0, 1, null, NOT_MARKED) - final range4 = new Range(0, 1, null, NEGATIVE_MARK) + final range1 = new RangeImpl(0, 1, null, NOT_MARKED) + final range2 = new RangeImpl(0, 1, null, VulnerabilityMarks.SQL_INJECTION_MARK) + final range3 = new RangeImpl(0, 1, null, NOT_MARKED) + final range4 = new RangeImpl(0, 1, null, NEGATIVE_MARK) final Range[] allNotMarked = [range1, range3] final Range[] notAllMarked = [range1, range2, range3, range4] final Range[] allMarked = [range2, range4] @@ -121,8 +122,8 @@ class RangesTest extends DDSpecification { void 'copyWithPosition'() { given: - final source = new Source(SourceTypes.NONE, null, null) - final range = new Range(0, 1, source, VulnerabilityMarks.SQL_INJECTION_MARK) + final source = new SourceImpl(SourceTypes.NONE, null, null) + final range = new RangeImpl(0, 1, source, VulnerabilityMarks.SQL_INJECTION_MARK) when: final result = Ranges.copyWithPosition(range, 2, 4) @@ -138,10 +139,10 @@ class RangesTest extends DDSpecification { void 'getNotMarkedRanges'(final int mark) { given: - final range1 = new Range(0, 1, null, NOT_MARKED) - final range2 = new Range(0, 1, null, mark) - final range3 = new Range(0, 1, null, NOT_MARKED) - final range4 = new Range(0, 1, null, mark) + final range1 = new RangeImpl(0, 1, null, NOT_MARKED) + final range2 = new RangeImpl(0, 1, null, mark) + final range3 = new RangeImpl(0, 1, null, NOT_MARKED) + final range4 = new RangeImpl(0, 1, null, mark) final Range[] allNotMarked = [range1, range3] final Range[] notAllMarked = [range1, range2, range3, range4] final Range[] allMarked = [range2, range4] @@ -385,36 +386,36 @@ class RangesTest extends DDSpecification { if (spec[i] == null) { continue } - ranges[i] = new Range( + ranges[i] = new RangeImpl( spec[i][0] as int, spec[i][1] as int, - new Source(SourceTypes.NONE, String.valueOf(j), null), + new SourceImpl(SourceTypes.NONE, String.valueOf(j), null), NOT_MARKED) j++ } ranges } - TaintedObject ranged(final int rangeCount) { + TaintedObjectEntry ranged(final int rangeCount) { final Range[] ranges = new Range[rangeCount] - return Mock(TaintedObject) { + return Mock(TaintedObjectEntry) { getRanges() >> ranges } } Range rangeFor(final int index) { - return new Range(index, 1, new Source(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) + return new RangeImpl(index, 1, new SourceImpl(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) } Range rangeWithSource(final byte source, final String name = 'name', final String value = 'value') { - return new Range(0, 10, new Source(source, name, value), NOT_MARKED) + return new RangeImpl(0, 10, new SourceImpl(source, name, value), NOT_MARKED) } Range range(final int start, final int length) { - return new Range(start, length, new Source(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) + return new RangeImpl(start, length, new SourceImpl(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) } Range rangeWithSource(final int start, final int length, final byte source, final String name = 'name', final String value = 'value') { - return new Range(start, length, new Source(source, name, value), NOT_MARKED) + return new RangeImpl(start, length, new SourceImpl(source, name, value), NOT_MARKED) } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintUtils.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintUtils.groovy index e7d8c4485c6..809d611ac6d 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintUtils.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintUtils.groovy @@ -1,8 +1,12 @@ package com.datadog.iast.taint -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source +import com.datadog.iast.model.SourceImpl import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.TaintedObject +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.api.iast.Taintable import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED @@ -58,7 +62,7 @@ class TaintUtils { assert length >= 0 int from = i + OPEN_MARK.length() String value = s.substring(from, from + length) - ranges.add(new Range(start, length, new Source(SourceTypes.NONE, null, value), mark)) + ranges.add(new RangeImpl(start, length, new SourceImpl(SourceTypes.NONE, null, value), mark)) pos += length i += OPEN_MARK.length() + length + CLOSE_MARK.length() - 1 } else { @@ -85,7 +89,7 @@ class TaintUtils { static TaintedObject getTaintedObject(final TaintedObjects tos, final Object target) { if (target instanceof Taintable) { final source = (target as Taintable).$$DD$getSource() as Source - return source == null ? null : new TaintedObject(target, Ranges.forObject(source)) + return source == null ? null : new TaintedObjectEntry(target, Ranges.forObject(source)) } return tos.get(target) } @@ -94,7 +98,7 @@ class TaintUtils { if (value instanceof String) { return addFromTaintFormat(tos, value as String) } - tos.taint(value, Ranges.forObject(new Source(SourceTypes.NONE, null, null))) + tos.taint(value, Ranges.forObject(new SourceImpl(SourceTypes.NONE, null, null))) return value } @@ -145,7 +149,7 @@ class TaintUtils { static Range toRange(String string, int start, int length) { final value = string.substring(start, start + length) - new Range(start, length, new Source(SourceTypes.NONE, null, value), NOT_MARKED) + new RangeImpl(start, length, new SourceImpl(SourceTypes.NONE, null, value), NOT_MARKED) } static Range[] toRanges(String string, List> lst) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedMapTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedMapTest.groovy index ad7f7499d9d..761989acf70 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedMapTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedMapTest.groovy @@ -2,7 +2,7 @@ package com.datadog.iast.taint import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger -import com.datadog.iast.model.Range +import datadog.trace.api.iast.taint.Range import datadog.trace.api.config.IastConfig import datadog.trace.api.iast.telemetry.IastMetric import datadog.trace.api.iast.telemetry.IastMetricCollector @@ -36,7 +36,7 @@ class TaintedMapTest extends DDSpecification { given: final map = new TaintedMap.TaintedMapImpl() final o = new Object() - final to = new TaintedObject(o, [] as Range[]) + final to = new TaintedObjectEntry(o, [] as Range[]) expect: map.size() == 0 @@ -81,7 +81,7 @@ class TaintedMapTest extends DDSpecification { expect: (1..nTotalObjects).each { i -> final o = new Object() - final to = new TaintedObject(o, [] as Range[]) + final to = new TaintedObjectEntry(o, [] as Range[]) map.put(to) assert map.get(o) == to } @@ -102,7 +102,7 @@ class TaintedMapTest extends DDSpecification { when: (1..iters).each { final queue = gen.genObjects(nObjectsPerIter, ObjectGen.TRUE).collect { o -> - final to = new TaintedObject(o, [] as Range[]) + final to = new TaintedObjectEntry(o, [] as Range[]) map.put(to) return to } @@ -115,7 +115,7 @@ class TaintedMapTest extends DDSpecification { queue.clear() // Trigger purge final o = gen.genObjects(1, ObjectGen.TRUE)[0] - final to = new TaintedObject(o, [] as Range[]) + final to = new TaintedObjectEntry(o, [] as Range[]) objectBuffer.add(o) map.put(to) } @@ -154,7 +154,7 @@ class TaintedMapTest extends DDSpecification { latch.countDown() latch.await() buckets[thread].each { o -> - final to = new TaintedObject(o, [] as Range[]) + final to = new TaintedObjectEntry(o, [] as Range[]) map.put(to) } } as Runnable) @@ -195,7 +195,7 @@ class TaintedMapTest extends DDSpecification { // Each thread has multiple objects for each bucket def objects = gen.genBuckets(capacity, nObjectsPerThread).flatten() def taintedObjects = objects.collect { o -> - return new TaintedObject(o, [] as Range[]) + return new TaintedObjectEntry(o, [] as Range[]) } Collections.shuffle(taintedObjects) @@ -229,7 +229,7 @@ class TaintedMapTest extends DDSpecification { final capacity = 1 // single bucket final map = new TaintedMap.TaintedMapImpl(1) final gen = new ObjectGen(capacity) - final to = gen.genObjects(5, ObjectGen.TRUE).collect { new TaintedObject(it, [] as Range[]) } + final to = gen.genObjects(5, ObjectGen.TRUE).collect { new TaintedObjectEntry(it, [] as Range[]) } when: 'purging the head with put' map.put(to[0]) @@ -265,7 +265,7 @@ class TaintedMapTest extends DDSpecification { final toTaint = 'test' when: - final tainted = instance.put(new TaintedObject(toTaint, [] as Range[])) + final tainted = instance.put(new TaintedObjectEntry(toTaint, [] as Range[])) then: tainted == null @@ -283,7 +283,7 @@ class TaintedMapTest extends DDSpecification { logger.setLevel(Level.ALL) when: - gen.genObjects(capacity, ObjectGen.TRUE).each { map.put(new TaintedObject(it, [] as Range[])) } + gen.genObjects(capacity, ObjectGen.TRUE).each { map.put(new TaintedObjectEntry(it, [] as Range[])) } then: map.size() == capacity @@ -297,7 +297,7 @@ class TaintedMapTest extends DDSpecification { final purge = new MockAgentTaskScheduler() final map = new TaintedMap.TaintedMapImpl(4, TaintedMap.DEFAULT_MAX_BUCKET_SIZE, maxAge, maxAgeUnit, purge) final items = (0..10).collect { it.toString() } - items.each { map.put(new TaintedObject(it, [] as Range[])) } + items.each { map.put(new TaintedObjectEntry(it, [] as Range[])) } when: 'first purge is called' purge.triggerAll() @@ -327,7 +327,7 @@ class TaintedMapTest extends DDSpecification { final map = new TaintedMap.TaintedMapImpl(1, 1, 1, TimeUnit.HOURS) when: - map.put(new TaintedObject('test1', new Range[0])) + map.put(new TaintedObjectEntry('test1', new Range[0])) then: map.count() == 1 @@ -336,7 +336,7 @@ class TaintedMapTest extends DDSpecification { fetchMetrics(collector).empty when: - map.put(new TaintedObject('test2', new Range[0])) + map.put(new TaintedObjectEntry('test2', new Range[0])) then: map.count() == 1 diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectTest.groovy index e528247b347..b452a0bdb2d 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectTest.groovy @@ -2,8 +2,9 @@ package com.datadog.iast.taint import ch.qos.logback.classic.Logger import ch.qos.logback.core.Appender -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import datadog.trace.api.iast.taint.Range +import com.datadog.iast.model.SourceImpl import datadog.trace.api.Config import spock.lang.Specification @@ -16,10 +17,10 @@ class TaintedObjectTest extends Specification { given: final max = Config.get().iastMaxRangeCount final ranges = (0..max + 1) - .collect { index -> new Range(index, 1, new Source(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) } + .collect { index -> new RangeImpl(index, 1, new SourceImpl(REQUEST_HEADER_NAME, 'a', 'b'), NOT_MARKED) } when: - final tainted = new TaintedObject('test', ranges.toArray(new Range[0])) + final tainted = new TaintedObjectEntry('test', ranges.toArray(new Range[0])) then: ranges.size() > max @@ -30,8 +31,8 @@ class TaintedObjectTest extends Specification { void 'test that objects are not tainted if null ranges are provided'() { setup: def toTaint = UUID.randomUUID().toString() - def to = new TaintedObject(toTaint, Ranges.forCharSequence(toTaint, new Source(1 as byte, 'a', 'b'), NOT_MARKED)) - def logger = TaintedObject.LOGGER as Logger + def to = new TaintedObjectEntry(toTaint, Ranges.forCharSequence(toTaint, new SourceImpl(1 as byte, 'a', 'b'), NOT_MARKED)) + def logger = TaintedObjectEntry.LOGGER as Logger def appender = Mock(Appender) logger.addAppender(appender) @@ -52,10 +53,10 @@ class TaintedObjectTest extends Specification { logger.detachAppender(appender) where: - ranges | taint - null | false - [] | true - [new Range(0, 10, new Source(1 as byte, 'a', 'b'), 1), null] | false - [new Range(0, 10, new Source(1 as byte, 'a', 'b'), 1), new Range(0, 10, new Source(2 as byte, 'a', 'b'), 1)] | true + ranges | taint + null | false + [] | true + [new RangeImpl(0, 10, new SourceImpl(1 as byte, 'a', 'b'), 1), null] | false + [new RangeImpl(0, 10, new SourceImpl(1 as byte, 'a', 'b'), 1), new RangeImpl(0, 10, new SourceImpl(2 as byte, 'a', 'b'), 1)] | true } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsLogTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsLogTest.groovy index 5fc3c2deed3..2bdea823d7d 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsLogTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsLogTest.groovy @@ -3,8 +3,9 @@ package com.datadog.iast.taint import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import com.datadog.iast.IastSystem -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.test.util.DDSpecification import groovy.transform.CompileDynamic @@ -19,7 +20,7 @@ class TaintedObjectsLogTest extends DDSpecification { void setup() { defaultDebug = IastSystem.DEBUG - logger = TaintedObjects.TaintedObjectsDebugAdapter.LOGGER as Logger + logger = TaintedObjectsDebugAdapter.LOGGER as Logger defaultLevel = logger.getLevel() } @@ -36,7 +37,7 @@ class TaintedObjectsLogTest extends DDSpecification { final value = "A" when: - def tainted = taintedObjects.taint(value, Ranges.forCharSequence(value, new Source(SourceTypes.NONE, null, null))) + def tainted = taintedObjects.taint(value, Ranges.forCharSequence(value, new SourceImpl(SourceTypes.NONE, null, null))) then: noExceptionThrown() @@ -56,7 +57,7 @@ class TaintedObjectsLogTest extends DDSpecification { logger.level = Level.ALL TaintedObjects taintedObjects = taintedObjects() final obj = 'A' - taintedObjects.taint(obj, Ranges.forCharSequence(obj, new Source(SourceTypes.NONE, null, null))) + taintedObjects.taint(obj, Ranges.forCharSequence(obj, new SourceImpl(SourceTypes.NONE, null, null))) when: taintedObjects.clear() @@ -73,7 +74,7 @@ class TaintedObjectsLogTest extends DDSpecification { final obj = 'A' when: - taintedObjects.taint(obj, Ranges.forCharSequence(obj, new Source(SourceTypes.NONE, null, null))) + taintedObjects.taint(obj, Ranges.forCharSequence(obj, new SourceImpl(SourceTypes.NONE, null, null))) then: taintedObjects.size() == 1 diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsMapTest.groovy similarity index 50% rename from dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsTest.groovy rename to dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsMapTest.groovy index ea096155ff5..1e1beafef79 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsMapTest.groovy @@ -2,17 +2,18 @@ package com.datadog.iast.taint import ch.qos.logback.classic.Logger import ch.qos.logback.core.Appender -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import spock.lang.Specification +import datadog.trace.api.iast.taint.Range -class TaintedObjectsTest extends Specification { +class TaintedObjectsMapTest extends Specification { void 'test that objects are not tainted if null ranges are provided'() { setup: def toTaint = UUID.randomUUID().toString() - def to = TaintedObjects.build(TaintedMap.build(8)) - def logger = TaintedObjects.LOGGER as Logger + def to = TaintedObjectsMap.build(TaintedMap.build(8)) + def logger = TaintedObjectsMap.LOGGER as Logger def appender = Mock(Appender) logger.addAppender(appender) @@ -23,9 +24,11 @@ class TaintedObjectsTest extends Specification { noExceptionThrown() if (taint) { to.get(toTaint) != null + to.isTainted(toTaint) 0 * appender.doAppend(_) } else { to.get(toTaint) == null + !to.isTainted(toTaint) 1 * appender.doAppend(_ as Object) } @@ -33,10 +36,10 @@ class TaintedObjectsTest extends Specification { logger.detachAppender(appender) where: - ranges | taint - null | false - [] | true - [new Range(0, 10, new Source(1 as byte, 'a', 'b'), 1), null] | false - [new Range(0, 10, new Source(1 as byte, 'a', 'b'), 1), new Range(0, 10, new Source(2 as byte, 'a', 'b'), 1)] | true + ranges | taint + null | false + [] | true + [new RangeImpl(0, 10, new SourceImpl(1 as byte, 'a', 'b'), 1), null] | false + [new RangeImpl(0, 10, new SourceImpl(1 as byte, 'a', 'b'), 1), new RangeImpl(0, 10, new SourceImpl(2 as byte, 'a', 'b'), 1)] | true } } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsNoOpTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsNoOpTest.groovy index 7de54e10dbe..14cccf0d596 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsNoOpTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedObjectsNoOpTest.groovy @@ -1,6 +1,7 @@ package com.datadog.iast.taint -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.TaintedObjects import spock.lang.Specification class TaintedObjectsNoOpTest extends Specification { @@ -12,7 +13,7 @@ class TaintedObjectsNoOpTest extends Specification { final toTaint = 'test' when: - final tainted = instance.taint(toTaint, Ranges.forCharSequence(toTaint, new Source(0 as byte, 'test', 'test'))) + final tainted = instance.taint(toTaint, Ranges.forCharSequence(toTaint, new SourceImpl(0 as byte, 'test', 'test'))) then: tainted == null diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedsTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedsTest.groovy index 1142bec4ad7..952fa2ed025 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedsTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/taint/TaintedsTest.groovy @@ -1,6 +1,6 @@ package com.datadog.iast.taint - +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.test.util.DDSpecification class TaintedsTest extends DDSpecification { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/TelemetryRequestEndedHandlerTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/TelemetryRequestEndedHandlerTest.groovy index 8969de34e6d..a11680a7787 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/TelemetryRequestEndedHandlerTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/TelemetryRequestEndedHandlerTest.groovy @@ -2,7 +2,7 @@ package com.datadog.iast.telemetry import com.datadog.iast.IastModuleImplTestBase import com.datadog.iast.RequestEndedHandler -import com.datadog.iast.model.Source +import com.datadog.iast.model.SourceImpl import com.datadog.iast.taint.Ranges import com.datadog.iast.telemetry.taint.TaintedObjectsWithTelemetry import datadog.trace.api.iast.InstrumentationBridge @@ -54,7 +54,7 @@ class TelemetryRequestEndedHandlerTest extends IastModuleImplTestBase { given: final handler = new TelemetryRequestEndedHandler(delegate) final toTaint = 'hello' - final source = new Source(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value') + final source = new SourceImpl(SourceTypes.REQUEST_PARAMETER_VALUE, 'name', 'value') ctx.taintedObjects.taint(toTaint, Ranges.forCharSequence(toTaint, source)) when: diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetryTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetryTest.groovy index 8b12618163f..b67a726ea3a 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetryTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/telemetry/taint/TaintedObjectsWithTelemetryTest.groovy @@ -1,7 +1,7 @@ package com.datadog.iast.telemetry.taint import com.datadog.iast.IastModuleImplTestBase -import com.datadog.iast.model.Range +import datadog.trace.api.iast.taint.Range import datadog.trace.api.iast.telemetry.IastMetric import datadog.trace.api.iast.telemetry.IastMetricCollector import datadog.trace.api.iast.telemetry.Verbosity diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangeBuilderTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangeBuilderTest.groovy index 4824b592b5e..eb3506c8346 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangeBuilderTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangeBuilderTest.groovy @@ -1,8 +1,9 @@ package com.datadog.iast.util -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl import com.datadog.iast.taint.Ranges +import datadog.trace.api.iast.taint.Range import spock.lang.Specification class RangeBuilderTest extends Specification { @@ -371,7 +372,7 @@ class RangeBuilderTest extends Specification { } static Range range(final int start) { - return new Range(start, 1, new Source((byte) 0, "name-${start}".toString(), "value-${start}".toString()), 0) + return new RangeImpl(start, 1, new SourceImpl((byte) 0, "name-${start}".toString(), "value-${start}".toString()), 0) } static Range[] asArray(final Collection ranges) { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedDequeueTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedDequeueTest.groovy index 71e89bb2da4..f60ca5099b2 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedDequeueTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedDequeueTest.groovy @@ -1,6 +1,7 @@ package com.datadog.iast.util import com.datadog.iast.sensitive.SensitiveHandler +import datadog.trace.api.iast.util.Ranged import spock.lang.Specification class RangedDequeueTest extends Specification { diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/StringUtilsTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/StringUtilsTest.groovy index 58e0aca69f3..08272b7a74c 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/StringUtilsTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/StringUtilsTest.groovy @@ -1,11 +1,13 @@ package com.datadog.iast.util -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source -import com.datadog.iast.taint.TaintedObjects +import com.datadog.iast.model.RangeImpl +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.TaintedObjects import spock.lang.Specification import java.util.regex.Pattern + import static datadog.trace.api.iast.VulnerabilityMarks.NOT_MARKED class StringUtilsTest extends Specification { @@ -123,6 +125,6 @@ class StringUtilsTest extends Specification { } Range range(final int start, final int length, final String name = 'name', final String value = 'value') { - return new Range(start, length, new Source((byte) 1, name, value), NOT_MARKED) + return new RangeImpl(start, length, new SourceImpl((byte) 1, name, value), NOT_MARKED) } } diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastAgentTestRunner.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastAgentTestRunner.groovy index 0ef01944533..44ef1c7474b 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastAgentTestRunner.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastAgentTestRunner.groovy @@ -1,7 +1,6 @@ package com.datadog.iast.test -import com.datadog.iast.model.Source -import com.datadog.iast.taint.TaintedObjects +import com.datadog.iast.model.SourceImpl import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor import datadog.trace.api.gateway.CallbackProvider @@ -9,6 +8,7 @@ import datadog.trace.api.gateway.Events import datadog.trace.api.gateway.RequestContextSlot import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.SourceTypes +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext @@ -16,7 +16,7 @@ import datadog.trace.core.DDSpan class IastAgentTestRunner extends AgentTestRunner implements IastRequestContextPreparationTrait { - public static final EMPTY_SOURCE = new Source(SourceTypes.NONE, '', '') + public static final EMPTY_SOURCE = new SourceImpl(SourceTypes.NONE, '', '') void configurePreAgent() { super.configurePreAgent() diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastHttpServerTest.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastHttpServerTest.groovy index 023d76ae82a..986df861add 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastHttpServerTest.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastHttpServerTest.groovy @@ -2,12 +2,12 @@ package com.datadog.iast.test import com.datadog.iast.IastRequestContext import com.datadog.iast.model.Vulnerability -import com.datadog.iast.taint.TaintedObjects import datadog.trace.agent.test.base.WithHttpServer import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor import datadog.trace.api.gateway.IGSpanInfo import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import groovy.json.JsonBuilder import groovy.transform.CompileStatic diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestContextPreparationTrait.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestContextPreparationTrait.groovy index 86fedac3cf2..68c652ad690 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestContextPreparationTrait.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestContextPreparationTrait.groovy @@ -1,12 +1,12 @@ package com.datadog.iast.test +import datadog.trace.api.iast.taint.Range import com.datadog.iast.IastRequestContext import com.datadog.iast.IastSystem -import com.datadog.iast.model.Range -import com.datadog.iast.taint.TaintedObject -import com.datadog.iast.taint.TaintedObjects import datadog.trace.api.gateway.* import datadog.trace.api.iast.InstrumentationBridge +import datadog.trace.api.iast.taint.TaintedObject +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import org.slf4j.Logger import org.slf4j.LoggerFactory diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestTestRunner.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestTestRunner.groovy index 7d0a121d385..1627ccad63f 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestTestRunner.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/IastRequestTestRunner.groovy @@ -1,11 +1,11 @@ package com.datadog.iast.test import com.datadog.iast.IastRequestContext -import com.datadog.iast.taint.TaintedObjects import datadog.trace.agent.test.utils.OkHttpUtils import datadog.trace.api.gateway.IGSpanInfo import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import okhttp3.OkHttpClient import java.util.concurrent.LinkedBlockingQueue diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintMarkerHelpers.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintMarkerHelpers.groovy index 0a3d83586d7..88df074a865 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintMarkerHelpers.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintMarkerHelpers.groovy @@ -1,10 +1,12 @@ package com.datadog.iast.test +import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge class TaintMarkerHelpers { static t(Object o) { - def propagation = InstrumentationBridge.PROPAGATION - propagation.isTainted(o) ? "$o (tainted)" : o + final propagation = InstrumentationBridge.PROPAGATION + final to = IastContext.Provider.taintedObjects() + propagation.isTainted(to, o) ? "$o (tainted)" : o } } diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectCollection.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectCollection.groovy index d7ac5b3351d..a3de73fe325 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectCollection.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectCollection.groovy @@ -1,9 +1,11 @@ package com.datadog.iast.test -import com.datadog.iast.model.Range -import com.datadog.iast.model.Source -import com.datadog.iast.taint.TaintedObject -import com.datadog.iast.taint.TaintedObjects +import com.datadog.iast.model.SourceImpl +import datadog.trace.api.iast.taint.Range +import datadog.trace.api.iast.taint.Source +import com.datadog.iast.taint.TaintedObjectEntry +import datadog.trace.api.iast.taint.TaintedObject +import datadog.trace.api.iast.taint.TaintedObjects import groovy.transform.Canonical import groovy.transform.CompileStatic import org.hamcrest.BaseMatcher @@ -23,7 +25,7 @@ import static org.hamcrest.Matchers.nullValue class TaintedObjectCollection { private final TaintedObjects taintedObjects // holds strong references to the tainted objects - private final List coll + private final List coll TaintedObjectCollection(TaintedObjects tobjs) { this.taintedObjects = tobjs @@ -43,7 +45,7 @@ class TaintedObjectCollection { "TO{${to.get()}, ranges=${to.ranges}" } - static class MatchingDelegate extends BaseMatcher { + static class MatchingDelegate extends BaseMatcher { private Matcher valueMatcher List ranges = [] @@ -92,10 +94,10 @@ class TaintedObjectCollection { @Override boolean matches(Object obj) { - if (!(obj instanceof TaintedObject)) { + if (!(obj instanceof TaintedObjectEntry)) { return false } - TaintedObject tobj = obj + TaintedObjectEntry tobj = obj valueMatcher.matches(tobj.get()) && ranges.every { RangeMatcher rm -> tobj.ranges.any { range -> @@ -125,11 +127,11 @@ class TaintedObjectCollection { } private boolean matchesName(final Source source) { - source.name == Source.GARBAGE_COLLECTED_REF || name.matches(source.name) + source.name == SourceImpl.GARBAGE_COLLECTED_REF || name.matches(source.name) } private boolean matchesValue(final Source source) { - source.value == Source.GARBAGE_COLLECTED_REF || value.matches(source.value) + source.value == SourceImpl.GARBAGE_COLLECTED_REF || value.matches(source.value) } @Override diff --git a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectsUtils.groovy b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectsUtils.groovy index 02cc25f336a..2124f75971e 100644 --- a/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectsUtils.groovy +++ b/dd-java-agent/agent-iast/src/testFixtures/groovy/com/datadog/iast/test/TaintedObjectsUtils.groovy @@ -1,17 +1,18 @@ package com.datadog.iast.test import com.datadog.iast.taint.TaintedMap -import com.datadog.iast.taint.TaintedObjects +import com.datadog.iast.taint.TaintedObjectsMap +import datadog.trace.api.iast.taint.TaintedObjects class TaintedObjectsUtils { private static final int TEST_TAINTED_MAP_SIZE = 1 << 8 static TaintedObjects taintedObjects() { - return TaintedObjects.build(TaintedMap.build(TEST_TAINTED_MAP_SIZE)) + return TaintedObjectsMap.build(TaintedMap.build(TEST_TAINTED_MAP_SIZE)) } static TaintedObjects noOpTaintedObjects() { - return TaintedObjects.build(TaintedMap.NoOp.INSTANCE) + return TaintedObjectsMap.build(TaintedMap.NoOp.INSTANCE) } } diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitor.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitor.java index 1d644ba7580..e55e5f5b80d 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitor.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitor.java @@ -25,7 +25,7 @@ public class TaintableVisitor implements AsmVisitorWrapper { static volatile boolean ENABLED = true; private static final String INTERFACE_NAME = "datadog/trace/api/iast/Taintable"; - private static final String SOURCE_CLASS_NAME = "L" + INTERFACE_NAME + "$Source;"; + private static final String SOURCE_CLASS_NAME = "Ldatadog/trace/api/iast/taint/Source;"; private static final String FIELD_NAME = "$$DD$source"; private static final String GETTER_NAME = "$$DD$getSource"; private static final String SETTER_NAME = "$$DD$setSource"; diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/iast/TaintableEnumeration.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/iast/TaintableEnumeration.java index f1d67e3a8a0..3d7e9a69af2 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/iast/TaintableEnumeration.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/iast/TaintableEnumeration.java @@ -1,17 +1,17 @@ package datadog.trace.agent.tooling.iast; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.util.stacktrace.StackUtils; -import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Enumeration; +import javax.annotation.Nonnull; import javax.annotation.Nullable; public class TaintableEnumeration implements Enumeration { private static final String CLASS_NAME = TaintableEnumeration.class.getName(); - private final IastContext context; + private final TaintedObjects to; private final PropagationModule module; @@ -24,13 +24,13 @@ public class TaintableEnumeration implements Enumeration { private final Enumeration delegate; private TaintableEnumeration( - final IastContext ctx, - @NonNull final Enumeration delegate, - @NonNull final PropagationModule module, + @Nullable final TaintedObjects to, + @Nonnull final Enumeration delegate, + @Nonnull final PropagationModule module, final byte origin, @Nullable final CharSequence name, final boolean useValueAsName) { - this.context = ctx; + this.to = to; this.delegate = delegate; this.module = module; this.origin = origin; @@ -58,7 +58,7 @@ public String nextElement() { throw e; } try { - module.taintString(context, next, origin, name(next)); + module.taintObject(to, next, origin, name(next)); } catch (final Throwable e) { module.onUnexpectedException("Failed to taint enumeration", e); } @@ -77,20 +77,20 @@ private static boolean nonTaintableEnumerationStack(final StackTraceElement elem } public static Enumeration wrap( - final IastContext ctx, - @NonNull final Enumeration delegate, - @NonNull final PropagationModule module, + @Nullable final TaintedObjects to, + @Nonnull final Enumeration delegate, + @Nonnull final PropagationModule module, final byte origin, @Nullable final CharSequence name) { - return new TaintableEnumeration(ctx, delegate, module, origin, name, false); + return new TaintableEnumeration(to, delegate, module, origin, name, false); } public static Enumeration wrap( - final IastContext ctx, - @NonNull final Enumeration delegate, - @NonNull final PropagationModule module, + @Nullable final TaintedObjects to, + @Nonnull final Enumeration delegate, + @Nonnull final PropagationModule module, final byte origin, boolean useValueAsName) { - return new TaintableEnumeration(ctx, delegate, module, origin, null, useValueAsName); + return new TaintableEnumeration(to, delegate, module, origin, null, useValueAsName); } } diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitorTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitorTest.groovy index 88a51e3ab35..75f0526a5bc 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitorTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/iast/TaintableVisitorTest.groovy @@ -2,6 +2,7 @@ package datadog.trace.agent.tooling.bytebuddy.iast import datadog.trace.agent.tooling.bytebuddy.LoadedTaintableClass import datadog.trace.api.iast.Taintable +import datadog.trace.api.iast.taint.Source import datadog.trace.test.util.DDSpecification import net.bytebuddy.ByteBuddy import net.bytebuddy.agent.ByteBuddyAgent @@ -31,7 +32,7 @@ class TaintableVisitorTest extends DDSpecification { void 'test taintable visitor'() { given: final className = 'datadog.trace.agent.tooling.bytebuddy.iast.TaintableTest' - final source = Mock(Taintable.Source) + final source = Mock(Source) final builder = new ByteBuddy() .subclass(Object) .name(className) @@ -66,7 +67,7 @@ class TaintableVisitorTest extends DDSpecification { void 'test taintable visitor with existing interface'() { given: final className = 'datadog.trace.agent.tooling.bytebuddy.iast.TaintableTest' - final source = Mock(Taintable.Source) + final source = Mock(Source) final builder = new ByteBuddy() .subclass(Cloneable) .name(className) diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/iast/TaintableEnumerationTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/iast/TaintableEnumerationTest.groovy index 4c3395004d7..ae52838b201 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/iast/TaintableEnumerationTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/iast/TaintableEnumerationTest.groovy @@ -1,17 +1,17 @@ package datadog.trace.agent.tooling.iast -import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.test.util.DDSpecification import spock.lang.Shared class TaintableEnumerationTest extends DDSpecification { @Shared - protected IastContext iastCtx = Stub(IastContext) + protected TaintedObjects to = Stub(TaintedObjects) protected PropagationModule module @@ -29,34 +29,34 @@ class TaintableEnumerationTest extends DDSpecification { final values = (1..10).collect { "value$it".toString() } final origin = SourceTypes.REQUEST_PARAMETER_NAME final name = 'test' - final enumeration = TaintableEnumeration.wrap(iastCtx, Collections.enumeration(values), module, origin, name) + final enumeration = TaintableEnumeration.wrap(to, Collections.enumeration(values), module, origin, name) when: final result = enumeration.collect() then: result == values - values.each { 1 * module.taintString(iastCtx, it, origin, name) } + values.each { 1 * module.taintObject(to, it, origin, name) } } void 'underlying enumerated values are tainted with the value as a name'() { given: final values = (1..10).collect { "value$it".toString() } final origin = SourceTypes.REQUEST_PARAMETER_NAME - final enumeration = TaintableEnumeration.wrap(iastCtx, Collections.enumeration(values), module, origin, true) + final enumeration = TaintableEnumeration.wrap(to, Collections.enumeration(values), module, origin, true) when: final result = enumeration.collect() then: result == values - values.each { 1 * module.taintString(iastCtx, it, origin, it) } + values.each { 1 * module.taintObject(to, it, origin, it) } } void 'taintable enumeration leaves no trace in case of error'() { given: final origin = SourceTypes.REQUEST_PARAMETER_NAME - final enumeration = TaintableEnumeration.wrap(iastCtx, new BadEnumeration(), module, origin, true) + final enumeration = TaintableEnumeration.wrap(to, new BadEnumeration(), module, origin, true) when: enumeration.hasMoreElements() diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/CookieHeaderInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/CookieHeaderInstrumentation.java index 5539fb450c6..45772b2983d 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/CookieHeaderInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/CookieHeaderInstrumentation.java @@ -11,17 +11,14 @@ import akka.http.scaladsl.model.headers.Cookie; import akka.http.scaladsl.model.headers.HttpCookiePair; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import scala.collection.Iterator; import scala.collection.immutable.Seq; @@ -54,20 +51,17 @@ public void methodAdvice(MethodTransformer transformer) { CookieHeaderInstrumentation.class.getName() + "$TaintAllCookiesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class TaintAllCookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) static void after( - @Advice.This HttpHeader cookie, - @Advice.Return Seq cookiePairs, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This HttpHeader cookie, @Advice.Return Seq cookiePairs) { PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || cookiePairs == null || cookiePairs.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!prop.isTainted(ctx, cookie)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!prop.isTainted(to, cookie)) { return; } @@ -75,8 +69,8 @@ static void after( while (iterator.hasNext()) { HttpCookiePair pair = iterator.next(); final String name = pair.name(), value = pair.value(); - prop.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HeaderNameCallSite.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HeaderNameCallSite.java index 143f2829989..edf3efbf7ee 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HeaderNameCallSite.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HeaderNameCallSite.java @@ -8,7 +8,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; /** * Detects when a header name is directly called from user code. This uses call site instrumentation @@ -28,11 +28,11 @@ public static String after(@CallSite.This HttpHeader header, @CallSite.Return St return result; } try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return result; } - module.taintStringIfTainted(ctx, result, header, SourceTypes.REQUEST_HEADER_NAME, result); + module.taintObjectIfTainted(to, result, header, SourceTypes.REQUEST_HEADER_NAME, result); } catch (final Throwable e) { module.onUnexpectedException("onHeaderNames threw", e); } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpHeaderSubclassesInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpHeaderSubclassesInstrumentation.java index e87100071cc..f394bc19f9b 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpHeaderSubclassesInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpHeaderSubclassesInstrumentation.java @@ -11,16 +11,13 @@ import akka.http.scaladsl.model.HttpHeader; import akka.http.scaladsl.model.HttpRequest; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -28,7 +25,6 @@ /** * Propagates taint from {@link HttpHeader} to their values, when they're retrieved. * - * @see MakeTaintableInstrumentation makes {@link HttpHeader} taintable * @see HttpRequestInstrumentation propagates taint from {@link HttpRequest} to the headers, when * they're retrieved */ @@ -58,21 +54,17 @@ public void methodAdvice(MethodTransformer transformer) { HttpHeaderSubclassesInstrumentation.class.getName() + "$HttpHeaderSubclassesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class HttpHeaderSubclassesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation - static void onExit( - @Advice.This HttpHeader h, - @Advice.Return String retVal, - @ActiveRequestContext RequestContext reqCtx) { + static void onExit(@Advice.This HttpHeader h, @Advice.Return String retVal) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintStringIfTainted(ctx, retVal, h); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, retVal, h); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpRequestInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpRequestInstrumentation.java index 49553f13bcb..7983541cfe1 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/HttpRequestInstrumentation.java @@ -12,28 +12,21 @@ import akka.http.scaladsl.model.HttpHeader; import akka.http.scaladsl.model.HttpRequest; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.bytebuddy.asm.Advice; import scala.collection.Iterator; import scala.collection.immutable.Seq; -/** - * Propagates taint from the {@link HttpRequest} to the headers and to the entity. - * - * @see MakeTaintableInstrumentation makes {@link HttpRequest} taintable - */ +/** Propagates taint from the {@link HttpRequest} to the headers and to the entity. */ @AutoService(InstrumenterModule.class) public class HttpRequestInstrumentation extends InstrumenterModule.Iast implements Instrumenter.ForSingleType { @@ -62,57 +55,52 @@ public void methodAdvice(MethodTransformer transformer) { } @SuppressFBWarnings("BC_IMPOSSIBLE_INSTANCEOF") - @RequiresRequestContext(RequestContextSlot.IAST) static class RequestHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) static void onExit( - @Advice.This HttpRequest thiz, - @Advice.Return(readOnly = false) Seq headers, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This HttpRequest thiz, @Advice.Return(readOnly = false) Seq headers) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || headers == null || headers.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!propagation.isTainted(ctx, thiz)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!propagation.isTainted(to, thiz)) { return; } Iterator iterator = headers.iterator(); while (iterator.hasNext()) { HttpHeader h = iterator.next(); - if (propagation.isTainted(ctx, h)) { + if (propagation.isTainted(to, h)) { continue; } // unfortunately, the call to h.value() is instrumented, but // because the call to taint() only happens after, the call is a noop - propagation.taintObject(ctx, h, SourceTypes.REQUEST_HEADER_VALUE, h.name(), h.value()); + propagation.taintObject(to, h, SourceTypes.REQUEST_HEADER_VALUE, h.name(), h.value()); } } } - @RequiresRequestContext(RequestContextSlot.IAST) static class EntityAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation static void onExit( @Advice.This HttpRequest thiz, - @Advice.Return(readOnly = false, typing = DYNAMIC) Object entity, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false, typing = DYNAMIC) Object entity) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || entity == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, entity)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, entity)) { return; } - propagation.taintObjectIfTainted(ctx, entity, thiz); + propagation.taintObjectIfTainted(to, entity, thiz); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/PathMatcherInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/PathMatcherInstrumentation.java index f3b26731b54..dccc6945a4d 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/PathMatcherInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/PathMatcherInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** @@ -46,12 +43,10 @@ public void methodAdvice(MethodTransformer transformer) { PathMatcherInstrumentation.class.getName() + "$PathMatcherAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class PathMatcherAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PATH_PARAMETER) - static void onExit( - @Advice.Argument(1) Object extractions, @ActiveRequestContext RequestContext reqCtx) { + static void onExit(@Advice.Argument(1) Object extractions) { if (!(extractions instanceof scala.Tuple1)) { return; } @@ -65,14 +60,14 @@ static void onExit( } final String stringValue = (String) value; - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); // in the test, 4 instances of PathMatcher$Match are created, all with the same value - if (module.isTainted(ctx, stringValue)) { + if (module.isTainted(to, stringValue)) { return; } - module.taintString(ctx, stringValue, SourceTypes.REQUEST_PATH_PARAMETER); + module.taintObject(to, stringValue, SourceTypes.REQUEST_PATH_PARAMETER); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/RequestContextInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/RequestContextInstrumentation.java index 90e897fcc7b..004a8bbd6bf 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/RequestContextInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/RequestContextInstrumentation.java @@ -10,15 +10,13 @@ import akka.http.scaladsl.model.HttpRequest; import akka.http.scaladsl.server.RequestContext; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.bytebuddy.asm.Advice; @@ -47,27 +45,27 @@ public void methodAdvice(MethodTransformer transformer) { } @SuppressFBWarnings("BC_IMPOSSIBLE_INSTANCEOF") - @RequiresRequestContext(RequestContextSlot.IAST) static class GetRequestAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation static void onExit( - @Advice.This RequestContext requestContext, - @Advice.Return HttpRequest request, - @ActiveRequestContext datadog.trace.api.gateway.RequestContext reqCtx) { + @Advice.This RequestContext requestContext, @Advice.Return HttpRequest request) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { + return; + } - if (propagation.isTainted(ctx, request)) { + if (propagation.isTainted(to, request)) { return; } - propagation.taintObjectIfTainted(ctx, request, requestContext); + propagation.taintObjectIfTainted(to, request, requestContext); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/UriInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/UriInstrumentation.java index 33ab666f6c3..2a99779ffcd 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/UriInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/UriInstrumentation.java @@ -10,18 +10,15 @@ import akka.http.scaladsl.model.Uri; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import scala.Tuple2; import scala.collection.Iterator; @@ -67,41 +64,33 @@ public void methodAdvice(MethodTransformer transformer) { UriInstrumentation.class.getName() + "$TaintQueryAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class TaintQueryStringAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation - static void after( - @Advice.This Uri uri, - @Advice.Return scala.Option ret, - @ActiveRequestContext RequestContext reqCtx) { + static void after(@Advice.This Uri uri, @Advice.Return scala.Option ret) { PropagationModule mod = InstrumentationBridge.PROPAGATION; if (mod == null || ret.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - mod.taintStringIfTainted(ctx, ret.get(), uri); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + mod.taintObjectIfTainted(to, ret.get(), uri); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintQueryAdvice { // bind uri to a variable of type Object so that this advice can also // be used from FromDataInstrumentaton @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - static void after( - @Advice.This /*Uri*/ Object uri, - @Advice.Return Uri.Query ret, - @ActiveRequestContext RequestContext reqCtx) { + static void after(@Advice.This /*Uri*/ Object uri, @Advice.Return Uri.Query ret) { PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || ret.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); - if (!prop.isTainted(ctx, uri)) { + if (!prop.isTainted(to, uri)) { return; } @@ -109,8 +98,8 @@ static void after( while (iterator.hasNext()) { Tuple2 pair = iterator.next(); final String name = pair._1(), value = pair._2(); - prop.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintCookieFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintCookieFunction.java index 5cbc18d95e1..ace8cfbc5e9 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintCookieFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintCookieFunction.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -21,14 +21,14 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null || httpCookiePair == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } final String name = httpCookiePair.name(); final String value = httpCookiePair.value(); - mod.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - mod.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + mod.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + mod.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); return v1; } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintFutureHelper.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintFutureHelper.java index b7153bef168..d2568075af0 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintFutureHelper.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintFutureHelper.java @@ -2,7 +2,7 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.compat.java8.JFunction1; import scala.concurrent.ExecutionContext; import scala.concurrent.Future; @@ -12,9 +12,9 @@ public static Future wrapFuture( Future f, Object input, PropagationModule mod, ExecutionContext ec) { JFunction1 mapf = t -> { - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - mod.taintObjectIfTainted(ctx, t, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + mod.taintObjectIfTainted(to, t, input); } return t; }; diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMapFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMapFunction.java index d8485bfa4b9..ed9d70abebd 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMapFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMapFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.Tuple2; import scala.collection.Iterator; @@ -24,16 +24,16 @@ public Tuple1> apply(Tuple1> v1) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } Iterator> iterator = m.iterator(); while (iterator.hasNext()) { Tuple2 e = iterator.next(); final String name = e._1(), value = e._2(); - prop.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } return v1; diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMultiMapFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMultiMapFunction.java index e98b45866b7..29c9962f013 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMultiMapFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintMultiMapFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.Tuple2; import scala.collection.Iterator; @@ -25,18 +25,18 @@ public Tuple1>> apply(Tuple1>> return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } Iterator>> entriesIterator = m.iterator(); while (entriesIterator.hasNext()) { Tuple2> e = entriesIterator.next(); final String name = e._1(); - mod.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + mod.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); List values = e._2(); for (final String value : ScalaToJava.listAsList(values)) { - mod.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintOptionalCookieFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintOptionalCookieFunction.java index 1aeb51bec1b..fa339ddd904 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintOptionalCookieFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintOptionalCookieFunction.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Option; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -22,15 +22,15 @@ public Tuple1> apply(Tuple1> v1) { if (mod == null || httpCookiePair == null || httpCookiePair.isEmpty()) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } final HttpCookiePair cookie = httpCookiePair.get(); final String name = cookie.name(); final String value = cookie.value(); - mod.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - mod.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + mod.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + mod.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); return v1; } } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestContextFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestContextFunction.java index 4839211d196..416e2e6ef76 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestContextFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestContextFunction.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -21,11 +21,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null || reqCtx == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, reqCtx, SourceTypes.REQUEST_BODY); + mod.taintObject(to, reqCtx, SourceTypes.REQUEST_BODY); return v1; } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestFunction.java index c881037cf1c..c421b60df16 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintRequestFunction.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -22,11 +22,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null || httpRequest == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, httpRequest, SourceTypes.REQUEST_BODY); + mod.taintObject(to, httpRequest, SourceTypes.REQUEST_BODY); return v1; } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintSeqFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintSeqFunction.java index 1269d8ef448..5a5fbc0fb18 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintSeqFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintSeqFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Set; @@ -28,8 +28,8 @@ public Tuple1>> apply(Tuple1> iterator = seq.iterator(); @@ -39,9 +39,9 @@ public Tuple1>> apply(Tuple1 apply(Tuple1 v1) { value = option.get(); } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } if (value instanceof Iterable) { @@ -50,11 +50,11 @@ public Tuple1 apply(Tuple1 v1) { while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof String) { - mod.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else if (value instanceof String) { - mod.taintString(ctx, (String) value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } return v1; diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUnmarshaller.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUnmarshaller.java index e993056d629..b4d6939be72 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUnmarshaller.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUnmarshaller.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.instrumentation.akkahttp.iast.UnmarshallerInstrumentation; import scala.Function1; import scala.PartialFunction; @@ -30,9 +30,9 @@ public TaintUnmarshaller(PropagationModule propagationModule, Unmarshaller @Override public Future apply(A value, ExecutionContext ec, Materializer materializer) { - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - propagationModule.taintObject(ctx, value, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + propagationModule.taintObject(to, value, SourceTypes.REQUEST_BODY); } return delegate.apply(value, ec, materializer); } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUriFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUriFunction.java index bad8548853e..cc1a19fd2a9 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUriFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/iast/helpers/TaintUriFunction.java @@ -5,7 +5,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -20,11 +20,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, uri, SourceTypes.REQUEST_QUERY); + mod.taintObject(to, uri, SourceTypes.REQUEST_QUERY); return v1; } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/ParameterDirectivesImplInstrumentation.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/ParameterDirectivesImplInstrumentation.java index 52804298683..5abe7e9e57b 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/ParameterDirectivesImplInstrumentation.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/ParameterDirectivesImplInstrumentation.java @@ -11,16 +11,13 @@ import akka.http.scaladsl.server.Directive; import akka.http.scaladsl.server.util.Tupler$; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.instrumentation.akkahttp102.iast.helpers.TaintParametersFunction; import net.bytebuddy.asm.Advice; @@ -73,38 +70,38 @@ public void methodAdvice(MethodTransformer transformer) { ParameterDirectivesImplInstrumentation.class.getName() + "$RepeatedFilterAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class FilterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) static void after( @Advice.Argument(0) String paramName, - @Advice.Return(readOnly = false) Directive /*>*/ retval, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false) Directive /*>*/ retval) { try { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - retval = - retval.tmap( - new TaintParametersFunction(ctx, paramName), Tupler$.MODULE$.forTuple(null)); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + retval = + retval.tmap( + new TaintParametersFunction<>(to, paramName), Tupler$.MODULE$.forTuple(null)); + } } catch (Exception e) { throw new RuntimeException(e); // propagate so it's logged } } } - @RequiresRequestContext(RequestContextSlot.IAST) static class RepeatedFilterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) static void after( @Advice.Argument(0) String paramName, - @Advice.Return(readOnly = false) Directive /*>>*/ retval, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false) Directive /*>>*/ retval) { try { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - retval = - retval.tmap( - new TaintParametersFunction(ctx, paramName), Tupler$.MODULE$.forTuple(null)); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + retval = + retval.tmap( + new TaintParametersFunction<>(to, paramName), Tupler$.MODULE$.forTuple(null)); + } } catch (Exception e) { throw new RuntimeException(e); // propagate so it's logged } diff --git a/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/helpers/TaintParametersFunction.java b/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/helpers/TaintParametersFunction.java index a5d800fc236..26a7ebd44be 100644 --- a/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/helpers/TaintParametersFunction.java +++ b/dd-java-agent/instrumentation/akka-http/akka-http-10.2-iast/src/main/java/datadog/trace/instrumentation/akkahttp102/iast/helpers/TaintParametersFunction.java @@ -1,9 +1,9 @@ package datadog.trace.instrumentation.akkahttp102.iast.helpers; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Function1; import scala.Option; import scala.Tuple1; @@ -12,11 +12,11 @@ public class TaintParametersFunction implements Function1, Tuple1> { - private final IastContext ctx; + private final TaintedObjects to; private final String paramName; - public TaintParametersFunction(IastContext ctx, String paramName) { - this.ctx = ctx; + public TaintParametersFunction(TaintedObjects to, String paramName) { + this.to = to; this.paramName = paramName; } @@ -41,11 +41,11 @@ public Tuple1 apply(Tuple1 v1) { while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof String) { - mod.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else if (value instanceof String) { - mod.taintString(ctx, (String) value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } return v1; diff --git a/dd-java-agent/instrumentation/apache-httpcore-4/src/main/java/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentation.java b/dd-java-agent/instrumentation/apache-httpcore-4/src/main/java/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentation.java index e4a6a223601..c23ab1d1065 100644 --- a/dd-java-agent/instrumentation/apache-httpcore-4/src/main/java/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpcore-4/src/main/java/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentation.java @@ -8,9 +8,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.apache.http.HttpHost; @@ -44,7 +46,8 @@ public static void afterCtor( @Advice.This final Object self, @Advice.Argument(0) final Object argument) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(self, argument); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, self, argument); } } } @@ -55,7 +58,8 @@ public static class ToUriAdvice { public static void methodExit(@Advice.This HttpHost self, @Advice.Return String result) { final PropagationModule propagationModule = InstrumentationBridge.PROPAGATION; if (propagationModule != null) { - propagationModule.taintObjectIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, self); } } } diff --git a/dd-java-agent/instrumentation/apache-httpcore-4/src/test/groovy/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentationTest.groovy b/dd-java-agent/instrumentation/apache-httpcore-4/src/test/groovy/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentationTest.groovy index f5b3d95bd20..440345218ec 100644 --- a/dd-java-agent/instrumentation/apache-httpcore-4/src/test/groovy/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/apache-httpcore-4/src/test/groovy/datadog/trace/instrumentation/apachehttpcore/IastHttpHostInstrumentationTest.groovy @@ -21,12 +21,12 @@ class IastHttpHostInstrumentationTest extends AgentTestRunner { HttpHost.newInstance(*args) then: - 1 * module.taintObjectIfTainted( _ as HttpHost, 'localhost') + 1 * module.taintObjectIfTainted(_, _ as HttpHost, 'localhost') where: - args | _ - ['localhost'] | _ - ['localhost', 8080] | _ + args | _ + ['localhost'] | _ + ['localhost', 8080] | _ ['localhost', 8080, 'http'] | _ } @@ -41,7 +41,7 @@ class IastHttpHostInstrumentationTest extends AgentTestRunner { httpHost.toURI() then: - 1 * module.taintObjectIfTainted(result, _ as HttpHost) + 1 * module.taintObjectIfTainted(_, result, _ as HttpHost) where: hostname | _ diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/CommonsFileuploadInstrumenter.java b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/CommonsFileuploadInstrumenter.java index 8c5ab41bb30..a2d3a7fc029 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/CommonsFileuploadInstrumenter.java +++ b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/CommonsFileuploadInstrumenter.java @@ -7,17 +7,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -48,20 +45,18 @@ public String[] knownMatchingTypes() { }; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ParseAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static Map onExit( - @Advice.Return final Map map, @ActiveRequestContext RequestContext reqCtx) { + public static Map onExit(@Advice.Return final Map map) { if (!map.isEmpty()) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Map.Entry entry : map.entrySet()) { if (entry.getValue() != null) { - module.taintString( - ctx, entry.getValue(), SourceTypes.REQUEST_MULTIPART_PARAMETER, entry.getKey()); + module.taintObject( + to, entry.getValue(), SourceTypes.REQUEST_MULTIPART_PARAMETER, entry.getKey()); } } } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemInstrumenter.java b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemInstrumenter.java index 2530351b72b..022038ce1b3 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemInstrumenter.java +++ b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemInstrumenter.java @@ -6,15 +6,12 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -46,17 +43,14 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$GetInputStreamAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetInputStreamAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit( - @Advice.Return final InputStream inputStream, - @Advice.This final FileItem self, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final InputStream inputStream, @Advice.This final FileItem self) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObjectIfTainted(ctx, inputStream, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, inputStream, self); } } } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemIteratorInstrumenter.java b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemIteratorInstrumenter.java index 0f27181d735..8eb39ac4790 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemIteratorInstrumenter.java +++ b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemIteratorInstrumenter.java @@ -6,15 +6,12 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -45,17 +42,15 @@ public void methodAdvice(MethodTransformer transformer) { named("next").and(isPublic()).and(takesArguments(0)), getClass().getName() + "$NextAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class NextAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit( @Advice.Return final FileItemStream fileItemStream, - @Advice.This final FileItemIterator self, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final FileItemIterator self) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObjectIfTainted(ctx, fileItemStream, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, fileItemStream, self); } } } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemStreamInstrumenter.java b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemStreamInstrumenter.java index 8b94da8df92..2c159cd9a14 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemStreamInstrumenter.java +++ b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/FileItemStreamInstrumenter.java @@ -6,15 +6,12 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -46,17 +43,14 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$OpenStreamAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class OpenStreamAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit( - @Advice.Return final InputStream inputStream, - @Advice.This final FileItemStream self, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final InputStream inputStream, @Advice.This final FileItemStream self) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObjectIfTainted(ctx, inputStream, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, inputStream, self); } } } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/ServletFileUploadInstrumenter.java b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/ServletFileUploadInstrumenter.java index 8808bf20db0..22b84f5dcbb 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/ServletFileUploadInstrumenter.java +++ b/dd-java-agent/instrumentation/commons-fileupload/src/main/java/datadog/trace/instrumentation/commons/fileupload/ServletFileUploadInstrumenter.java @@ -5,17 +5,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -54,53 +51,44 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$GetItemIteratorAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ParseRequestAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final List fileItems, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final List fileItems) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final FileItem fileItem : fileItems) { - module.taintObject(ctx, fileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER); + module.taintObject(to, fileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ParseParameterMapAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final Map> parameterMap, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Map> parameterMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (List fileItems : parameterMap.values()) { for (FileItem fileItem : fileItems) { - module.taintObject(ctx, fileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER); + module.taintObject(to, fileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetItemIteratorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final FileItemIterator fileItemIterator, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final FileItemIterator fileItemIterator) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, fileItemIterator, SourceTypes.REQUEST_MULTIPART_PARAMETER); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, fileItemIterator, SourceTypes.REQUEST_MULTIPART_PARAMETER); } } } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemInstrumenterTest.groovy b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemInstrumenterTest.groovy index 75206dc5c97..a11b3e8fdd5 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemInstrumenterTest.groovy +++ b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemInstrumenterTest.groovy @@ -2,6 +2,7 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockFileItem @@ -9,6 +10,7 @@ import foo.bar.smoketest.MockFileItem class FileItemInstrumenterTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -17,7 +19,10 @@ class FileItemInstrumenterTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -36,7 +41,7 @@ class FileItemInstrumenterTest extends AgentTestRunner { runUnderIastTrace { fileItem.getInputStream() } then: - 1 * module.taintObjectIfTainted(iastCtx, inputStream, fileItem) + 1 * module.taintObjectIfTainted(to, inputStream, fileItem) 0 * _ } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemIteratorInstrumenterTest.groovy b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemIteratorInstrumenterTest.groovy index 830914a2d6e..3ff77d57be6 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemIteratorInstrumenterTest.groovy +++ b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemIteratorInstrumenterTest.groovy @@ -2,6 +2,7 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockFileItemIterator @@ -10,6 +11,7 @@ import foo.bar.smoketest.MockFileItemStream class FileItemIteratorInstrumenterTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -18,7 +20,10 @@ class FileItemIteratorInstrumenterTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -37,7 +42,7 @@ class FileItemIteratorInstrumenterTest extends AgentTestRunner { runUnderIastTrace { fileItemIterator.next() } then: - 1 * module.taintObjectIfTainted(iastCtx, fileItemStreams, fileItemIterator) + 1 * module.taintObjectIfTainted(to, fileItemStreams, fileItemIterator) 0 * _ } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemStreamInstrumenterTest.groovy b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemStreamInstrumenterTest.groovy index ec70565f52c..b87d381581e 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemStreamInstrumenterTest.groovy +++ b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/FileItemStreamInstrumenterTest.groovy @@ -2,6 +2,7 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockFileItemStream @@ -9,6 +10,7 @@ import foo.bar.smoketest.MockFileItemStream class FileItemStreamInstrumenterTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -17,7 +19,10 @@ class FileItemStreamInstrumenterTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -36,7 +41,7 @@ class FileItemStreamInstrumenterTest extends AgentTestRunner { runUnderIastTrace { fileItemStream.openStream() } then: - 1 * module.taintObjectIfTainted(iastCtx, inputStream, fileItemStream) + 1 * module.taintObjectIfTainted(to, inputStream, fileItemStream) 0 * _ } diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/MultipartInstrumentationTest.groovy b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/MultipartInstrumentationTest.groovy index 4e9a90ad393..f5e4ce37b03 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/MultipartInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/MultipartInstrumentationTest.groovy @@ -3,6 +3,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext @@ -10,6 +11,7 @@ import datadog.trace.bootstrap.instrumentation.api.TagContext class MultipartInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -18,7 +20,10 @@ class MultipartInstrumentationTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -41,8 +46,8 @@ class MultipartInstrumentationTest extends AgentTestRunner { } then: - 1 * module.taintString(iastCtx, 'file', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'name') - 1 * module.taintString(iastCtx, _, SourceTypes.REQUEST_MULTIPART_PARAMETER, 'filename') + 1 * module.taintObject(to, 'file', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'name') + 1 * module.taintObject(to, _, SourceTypes.REQUEST_MULTIPART_PARAMETER, 'filename') 0 * _ where: diff --git a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/ServletFileUploadInstrumenterTest.groovy b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/ServletFileUploadInstrumenterTest.groovy index 629da4e6a93..5c803b7fce5 100644 --- a/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/ServletFileUploadInstrumenterTest.groovy +++ b/dd-java-agent/instrumentation/commons-fileupload/src/test/groovy/ServletFileUploadInstrumenterTest.groovy @@ -3,6 +3,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockHttpServletRequest @@ -14,6 +15,7 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload class ServletFileUploadInstrumenterTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -22,7 +24,10 @@ class ServletFileUploadInstrumenterTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -48,7 +53,7 @@ class ServletFileUploadInstrumenterTest extends AgentTestRunner { runUnderIastTrace { servletFileUpload.parseRequest(request) } then: - 1 * module.taintObject(iastCtx, _ as FileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, _ as FileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER) } void 'test commons fileupload ServletFileUpload parseParameterMap'() { @@ -69,7 +74,7 @@ class ServletFileUploadInstrumenterTest extends AgentTestRunner { runUnderIastTrace { servletFileUpload.parseParameterMap(request) } then: - 1 * module.taintObject(iastCtx, _ as FileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, _ as FileItem, SourceTypes.REQUEST_MULTIPART_PARAMETER) } void 'test commons fileupload ServletFileUpload getItemIterator'() { @@ -90,7 +95,7 @@ class ServletFileUploadInstrumenterTest extends AgentTestRunner { runUnderIastTrace { servletFileUpload.getItemIterator(request) } then: - 1 * module.taintObject(iastCtx, _ as FileItemIterator, SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, _ as FileItemIterator, SourceTypes.REQUEST_MULTIPART_PARAMETER) } protected E runUnderIastTrace(Closure cl) { diff --git a/dd-java-agent/instrumentation/commons-httpclient-2/src/main/java/datadog/trace/instrumentation/commonshttpclient/IastHttpMethodBaseInstrumentation.java b/dd-java-agent/instrumentation/commons-httpclient-2/src/main/java/datadog/trace/instrumentation/commonshttpclient/IastHttpMethodBaseInstrumentation.java index ecb21bfc025..bb11305a602 100644 --- a/dd-java-agent/instrumentation/commons-httpclient-2/src/main/java/datadog/trace/instrumentation/commonshttpclient/IastHttpMethodBaseInstrumentation.java +++ b/dd-java-agent/instrumentation/commons-httpclient-2/src/main/java/datadog/trace/instrumentation/commonshttpclient/IastHttpMethodBaseInstrumentation.java @@ -8,9 +8,11 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -52,7 +54,8 @@ public static void afterCtor( @Advice.This final Object self, @Advice.Argument(0) final Object argument) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(self, argument); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, self, argument); } } } diff --git a/dd-java-agent/instrumentation/commons-httpclient-2/src/test/groovy/IastCommonsHttpClientInstrumentationTest.groovy b/dd-java-agent/instrumentation/commons-httpclient-2/src/test/groovy/IastCommonsHttpClientInstrumentationTest.groovy index 1513c811159..39537992e5e 100644 --- a/dd-java-agent/instrumentation/commons-httpclient-2/src/test/groovy/IastCommonsHttpClientInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/commons-httpclient-2/src/test/groovy/IastCommonsHttpClientInstrumentationTest.groovy @@ -51,9 +51,9 @@ class IastCommonsHttpClientInstrumentationTest extends AgentTestRunner { private void mockPropagation() { final propagation = Mock(PropagationModule) { - taintObjectIfTainted(_, _) >> { - if (tainteds.containsKey(it[1])) { - tainteds.put(it[0], null) + taintObjectIfTainted(_, _, _) >> { + if (tainteds.containsKey(it[2])) { + tainteds.put(it[1], null) } } } diff --git a/dd-java-agent/instrumentation/commons-lang-2/src/main/java/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSite.java b/dd-java-agent/instrumentation/commons-lang-2/src/main/java/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSite.java index 23230f2e987..900b1923184 100644 --- a/dd-java-agent/instrumentation/commons-lang-2/src/main/java/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSite.java +++ b/dd-java-agent/instrumentation/commons-lang-2/src/main/java/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSite.java @@ -2,10 +2,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.VulnerabilityMarks; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.annotation.Nullable; @Propagation @@ -25,7 +27,8 @@ public static String afterEscape( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEscape threw", e); } @@ -40,7 +43,9 @@ public static String afterEscapeSQL( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.SQL_INJECTION_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, input, false, VulnerabilityMarks.SQL_INJECTION_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEscapeSQL threw", e); } diff --git a/dd-java-agent/instrumentation/commons-lang-2/src/test/groovy/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSiteTest.groovy b/dd-java-agent/instrumentation/commons-lang-2/src/test/groovy/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSiteTest.groovy index 4da4ca5d80a..a6e4fee47f7 100644 --- a/dd-java-agent/instrumentation/commons-lang-2/src/test/groovy/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/commons-lang-2/src/test/groovy/datadog/trace/instrumentation/commonslang/StringEscapeUtilsCallSiteTest.groovy @@ -27,7 +27,7 @@ class StringEscapeUtilsCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0], false, mark) + 1 * module.taintObjectIfTainted(_, _ as String, args[0], false, mark) 0 * _ where: diff --git a/dd-java-agent/instrumentation/commons-lang-3/src/main/java/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSite.java b/dd-java-agent/instrumentation/commons-lang-3/src/main/java/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSite.java index 4f5452e85d7..727b2dc6cb6 100644 --- a/dd-java-agent/instrumentation/commons-lang-3/src/main/java/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSite.java +++ b/dd-java-agent/instrumentation/commons-lang-3/src/main/java/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSite.java @@ -2,10 +2,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.VulnerabilityMarks; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.annotation.Nullable; @Propagation @@ -27,7 +29,8 @@ public static String afterEscape( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEscape threw", e); } @@ -42,7 +45,8 @@ public static String afterEscapeJson( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input); } catch (final Throwable e) { module.onUnexpectedException("afterEscapeJson threw", e); } diff --git a/dd-java-agent/instrumentation/commons-lang-3/src/test/groovy/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSiteTest.groovy b/dd-java-agent/instrumentation/commons-lang-3/src/test/groovy/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSiteTest.groovy index f4466dbed9a..15ba4448167 100644 --- a/dd-java-agent/instrumentation/commons-lang-3/src/test/groovy/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/commons-lang-3/src/test/groovy/datadog/trace/instrumentation/commonslang3/StringEscapeUtilsCallSiteTest.groovy @@ -25,7 +25,7 @@ class StringEscapeUtilsCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0], false, VulnerabilityMarks.XSS_MARK) + 1 * module.taintObjectIfTainted(_, _ as String, args[0], false, VulnerabilityMarks.XSS_MARK) 0 * _ where: @@ -47,7 +47,7 @@ class StringEscapeUtilsCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0]) + 1 * module.taintObjectIfTainted(_, _ as String, args[0]) 0 * _ where: diff --git a/dd-java-agent/instrumentation/commons-text/src/main/java/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSite.java b/dd-java-agent/instrumentation/commons-text/src/main/java/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSite.java index 0541ff8dcf4..d7775c469f8 100644 --- a/dd-java-agent/instrumentation/commons-text/src/main/java/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSite.java +++ b/dd-java-agent/instrumentation/commons-text/src/main/java/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSite.java @@ -2,10 +2,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.VulnerabilityMarks; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.annotation.Nullable; @Propagation @@ -29,7 +31,8 @@ public static String afterEscape( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEscape threw", e); } @@ -44,7 +47,8 @@ public static String afterEscapeJson( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input); } catch (final Throwable e) { module.onUnexpectedException("afterEscapeJson threw", e); } diff --git a/dd-java-agent/instrumentation/commons-text/src/test/groovy/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSiteTest.groovy b/dd-java-agent/instrumentation/commons-text/src/test/groovy/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSiteTest.groovy index b0fdcc353ce..fa8176d2f1d 100644 --- a/dd-java-agent/instrumentation/commons-text/src/test/groovy/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/commons-text/src/test/groovy/datadog/trace/instrumentation/commonstext/StringEscapeUtilsCallSiteTest.groovy @@ -25,7 +25,7 @@ class StringEscapeUtilsCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0], false, VulnerabilityMarks.XSS_MARK) + 1 * module.taintObjectIfTainted(_, _ as String, args[0], false, VulnerabilityMarks.XSS_MARK) 0 * _ where: @@ -48,7 +48,7 @@ class StringEscapeUtilsCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0]) + 1 * module.taintObjectIfTainted(_, _ as String, args[0]) 0 * _ where: diff --git a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker/StringUtilCallSite.java b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker/StringUtilCallSite.java index d73c66d920b..e37ea3e50b9 100644 --- a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker/StringUtilCallSite.java +++ b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker/StringUtilCallSite.java @@ -2,10 +2,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.VulnerabilityMarks; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.annotation.Nullable; @Propagation @@ -29,7 +31,8 @@ public static String afterEscape( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEscape threw", e); } diff --git a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentation.java b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentation.java index 0e521c04d7b..10b34d87dd3 100644 --- a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentation.java +++ b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/main/java/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentation.java @@ -6,16 +6,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import freemarker.template.TemplateModel; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -48,18 +45,15 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$ObjectWrapperAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ObjectWrapperAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation public static void onExit( - @Advice.Return final TemplateModel templateModel, - @Advice.Argument(0) final Object object, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final TemplateModel templateModel, @Advice.Argument(0) final Object object) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObjectIfTainted(ctx, templateModel, object); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, templateModel, object); } } } diff --git a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker/StringUtilCallSiteTest.groovy b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker/StringUtilCallSiteTest.groovy index 065a3e700a7..c1fff933249 100644 --- a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker/StringUtilCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker/StringUtilCallSiteTest.groovy @@ -23,7 +23,7 @@ class StringUtilCallSiteTest extends AgentTestRunner { then: result == expected - 1 * module.taintStringIfTainted(_ as String, args[0], false, VulnerabilityMarks.XSS_MARK) + 1 * module.taintObjectIfTainted(_, _ as String, args[0], false, VulnerabilityMarks.XSS_MARK) 0 * _ where: diff --git a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentationTest.groovy b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentationTest.groovy index f1db1a26a19..667b9bc6a8a 100644 --- a/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/freemarker/freemarker-2.3.24/src/test/groovy/datadog/trace/instrumentation/freemarker24/ObjectWrapperInstrumentationTest.groovy @@ -4,6 +4,7 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import freemarker.template.DefaultObjectWrapper @@ -11,6 +12,7 @@ import freemarker.template.DefaultObjectWrapper class ObjectWrapperInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -19,7 +21,10 @@ class ObjectWrapperInstrumentationTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -38,7 +43,7 @@ class ObjectWrapperInstrumentationTest extends AgentTestRunner { runUnderIastTrace { objectWrapper.wrap(wrapped) } then: - 1 * module.taintObjectIfTainted(iastCtx, _, wrapped) + 1 * module.taintObjectIfTainted(to, _, wrapped) 0 * _ } diff --git a/dd-java-agent/instrumentation/gson-1.6/src/main/java/datadog/trace/instrumentation/gson/JsonReaderInstrumentation.java b/dd-java-agent/instrumentation/gson-1.6/src/main/java/datadog/trace/instrumentation/gson/JsonReaderInstrumentation.java index a848155602e..b65e06636f6 100644 --- a/dd-java-agent/instrumentation/gson-1.6/src/main/java/datadog/trace/instrumentation/gson/JsonReaderInstrumentation.java +++ b/dd-java-agent/instrumentation/gson-1.6/src/main/java/datadog/trace/instrumentation/gson/JsonReaderInstrumentation.java @@ -14,9 +14,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.matcher.ElementMatcher; @@ -59,7 +61,8 @@ public static void afterInit( @Advice.This Object self, @Advice.Argument(0) final java.io.Reader input) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && input != null) { - iastModule.taintObjectIfTainted(self, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, self, input); } } } @@ -70,7 +73,8 @@ public static class MethodAdvice { public static void afterMethod(@Advice.This Object self, @Advice.Return final String result) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && result != null) { - iastModule.taintStringIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, result, self); } } } diff --git a/dd-java-agent/instrumentation/gson-1.6/src/test/groovy/datadog/trace/instrumentation/gson/JsonReaderInstrumentationTest.groovy b/dd-java-agent/instrumentation/gson-1.6/src/test/groovy/datadog/trace/instrumentation/gson/JsonReaderInstrumentationTest.groovy index 48065fceaaa..463ab948330 100644 --- a/dd-java-agent/instrumentation/gson-1.6/src/test/groovy/datadog/trace/instrumentation/gson/JsonReaderInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/gson-1.6/src/test/groovy/datadog/trace/instrumentation/gson/JsonReaderInstrumentationTest.groovy @@ -23,13 +23,13 @@ class JsonReaderInstrumentationTest extends AgentTestRunner { final reader = new JsonReader(new StringReader(json)) then: - 1 * module.taintObjectIfTainted(_ as JsonReader, _ as StringReader) + 1 * module.taintObjectIfTainted(_, _ as JsonReader, _ as StringReader) when: gson.fromJson(reader, clazz) then: - calls * module.taintStringIfTainted(_ as String, _ as JsonReader) + calls * module.taintObjectIfTainted(_, _ as String, _ as JsonReader) 0 * _ where: diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/main/java/datadog/trace/instrumentation/jackson/codehouse/core/Json1FactoryInstrumentation.java b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/main/java/datadog/trace/instrumentation/jackson/codehouse/core/Json1FactoryInstrumentation.java index 34ccea963d0..7f08715d92c 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/main/java/datadog/trace/instrumentation/jackson/codehouse/core/Json1FactoryInstrumentation.java +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/main/java/datadog/trace/instrumentation/jackson/codehouse/core/Json1FactoryInstrumentation.java @@ -9,12 +9,14 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Sink; import datadog.trace.api.iast.VulnerabilityTypes; import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.SsrfModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import java.io.Reader; import java.net.URL; @@ -61,7 +63,8 @@ public static void onExit( if (input != null) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - propagation.taintObjectIfTainted(parser, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, parser, input); } if (input instanceof URL) { final SsrfModule ssrf = InstrumentationBridge.SSRF; @@ -85,7 +88,9 @@ public static void onExit( if (input != null || length <= 0) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - propagation.taintObjectIfRangeTainted(parser, input, offset, length, false, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfRangeTainted( + to, parser, input, offset, length, false, NOT_MARKED); } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1FactoryInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1FactoryInstrumentationTest.groovy index dca6b8c3aa1..be338bce5bf 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1FactoryInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1FactoryInstrumentationTest.groovy @@ -41,7 +41,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, content) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, content) 0 * _ } @@ -56,7 +56,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, is) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, is) 2 * is.read(_, _, _) 0 * _ } @@ -73,7 +73,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, reader) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, reader) 0 * _ } @@ -89,7 +89,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: parser != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, url) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, url) 1 * ssrfModule.onURLConnection(url) 0 * _ } @@ -107,7 +107,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, bytes) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, bytes) 0 * _ } @@ -122,7 +122,7 @@ class Json1FactoryInstrumentationTest extends AgentTestRunner { then: parser != null - 1 * propagationModule.taintObjectIfRangeTainted(_ as JsonParser, bytes, 0, 2, false, VulnerabilityMarks.NOT_MARKED) + 1 * propagationModule.taintObjectIfRangeTainted(_, _ as JsonParser, bytes, 0, 2, false, VulnerabilityMarks.NOT_MARKED) 0 * _ } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1ParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1ParserInstrumentationTest.groovy index 847a5dbc044..5125c9f81b2 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1ParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-1/src/test/groovy/Json1ParserInstrumentationTest.groovy @@ -1,8 +1,8 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable.Source import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import org.codehaus.jackson.map.ObjectMapper @@ -31,14 +31,14 @@ class Json1ParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'root_value', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) - 1 * module.taintString(_, 'nested_array', source.origin, 'nested_array', JSON_STRING) - 1 * module.taintString(_, 'array_0', source.origin, 'nested_array', JSON_STRING) - 1 * module.taintString(_, 'array_1', source.origin, 'nested_array', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'root_value', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) + 1 * module.taintObject(_, 'nested_array', source.origin, 'nested_array', JSON_STRING) + 1 * module.taintObject(_, 'array_0', source.origin, 'nested_array', JSON_STRING) + 1 * module.taintObject(_, 'array_1', source.origin, 'nested_array', JSON_STRING) 0 * _ where: @@ -58,8 +58,8 @@ class Json1ParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -74,5 +74,20 @@ class Json1ParserInstrumentationTest extends AgentTestRunner { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.12/src/test/groovy/datadog/trace/instrumentation/jackson212/core/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.12/src/test/groovy/datadog/trace/instrumentation/jackson212/core/JsonParserInstrumentationTest.groovy index f8d78f98b08..899c90cc74c 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.12/src/test/groovy/datadog/trace/instrumentation/jackson212/core/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.12/src/test/groovy/datadog/trace/instrumentation/jackson212/core/JsonParserInstrumentationTest.groovy @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -34,10 +34,10 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) 0 * _ } @@ -56,8 +56,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source 0 * _ } @@ -74,8 +74,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -86,9 +86,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.16/src/test/groovy/datadog/trace/instrumentation/jackson216/core/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.16/src/test/groovy/datadog/trace/instrumentation/jackson216/core/JsonParserInstrumentationTest.groovy index 38f638ca8e3..d01e7f451e3 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.16/src/test/groovy/datadog/trace/instrumentation/jackson216/core/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.16/src/test/groovy/datadog/trace/instrumentation/jackson216/core/JsonParserInstrumentationTest.groovy @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -34,11 +34,11 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) - 1 * module.taintString(_, 'nested_array', source.origin, 'nested_array', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) + 1 * module.taintObject(_, 'nested_array', source.origin, 'nested_array', JSON_STRING) 0 * _ } @@ -57,8 +57,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source 0 * _ } @@ -75,8 +75,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -87,9 +87,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.6/src/test/groovy/datadog/trace/instrumentation/jackson26/core/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.6/src/test/groovy/datadog/trace/instrumentation/jackson26/core/JsonParserInstrumentationTest.groovy index c839bccf0c5..08e53413a90 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.6/src/test/groovy/datadog/trace/instrumentation/jackson26/core/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.6/src/test/groovy/datadog/trace/instrumentation/jackson26/core/JsonParserInstrumentationTest.groovy @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -34,10 +34,10 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) 0 * _ } @@ -56,8 +56,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source 0 * _ } @@ -74,8 +74,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -86,9 +86,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.8/src/test/groovy/datadog/trace/instrumentation/jackson28/core/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.8/src/test/groovy/datadog/trace/instrumentation/jackson28/core/JsonParserInstrumentationTest.groovy index 08c889db41c..6bd82200b25 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-2.8/src/test/groovy/datadog/trace/instrumentation/jackson28/core/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-2.8/src/test/groovy/datadog/trace/instrumentation/jackson28/core/JsonParserInstrumentationTest.groovy @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -34,10 +34,10 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) 0 * _ } @@ -56,8 +56,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source 0 * _ } @@ -74,8 +74,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -86,9 +86,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/jackson-core-2/src/test/groovy/datadog/trace/instrumentation/jackson2/core/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/jackson-core-2/src/test/groovy/datadog/trace/instrumentation/jackson2/core/JsonParserInstrumentationTest.groovy index 505ce50fce9..743a14f5aba 100644 --- a/dd-java-agent/instrumentation/jackson-core/jackson-core-2/src/test/groovy/datadog/trace/instrumentation/jackson2/core/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/jackson-core-2/src/test/groovy/datadog/trace/instrumentation/jackson2/core/JsonParserInstrumentationTest.groovy @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -34,10 +34,10 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root', source.origin, 'root', JSON_STRING) - 1 * module.taintString(_, 'nested', source.origin, 'nested', JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root', source.origin, 'root', JSON_STRING) + 1 * module.taintObject(_, 'nested', source.origin, 'nested', JSON_STRING) 0 * _ } @@ -56,8 +56,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source 0 * _ } @@ -74,8 +74,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -86,9 +86,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/Json2FactoryInstrumentation.java b/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/Json2FactoryInstrumentation.java index 968f82f03b4..4a1035f7e29 100644 --- a/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/Json2FactoryInstrumentation.java +++ b/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/Json2FactoryInstrumentation.java @@ -9,12 +9,14 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Sink; import datadog.trace.api.iast.VulnerabilityTypes; import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.SsrfModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import java.io.Reader; import java.net.URL; @@ -63,7 +65,8 @@ public static void onExit( if (input != null) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - propagation.taintObjectIfTainted(parser, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, parser, input); } if (input instanceof URL) { final SsrfModule ssrf = InstrumentationBridge.SSRF; @@ -87,7 +90,9 @@ public static void onExit( if (input != null || length <= 0) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - propagation.taintObjectIfRangeTainted(parser, input, offset, length, false, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfRangeTainted( + to, parser, input, offset, length, false, NOT_MARKED); } } } diff --git a/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/TokenBufferInstrumentation.java b/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/TokenBufferInstrumentation.java index b696d198684..2347dc29d03 100644 --- a/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/TokenBufferInstrumentation.java +++ b/dd-java-agent/instrumentation/jackson-core/src/main/java/datadog/trace/instrumentation/jackson/core/TokenBufferInstrumentation.java @@ -11,9 +11,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** @@ -50,7 +52,8 @@ public static void onExit( @Advice.This TokenBuffer tokenBuffer, @Advice.Return JsonParser parser) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(parser, tokenBuffer); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, parser, tokenBuffer); } } } diff --git a/dd-java-agent/instrumentation/jackson-core/src/test/groovy/Json2FactoryInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/src/test/groovy/Json2FactoryInstrumentationTest.groovy index 513e7e7ed17..7c71805e800 100644 --- a/dd-java-agent/instrumentation/jackson-core/src/test/groovy/Json2FactoryInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/src/test/groovy/Json2FactoryInstrumentationTest.groovy @@ -44,7 +44,7 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, content) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, content) 0 * _ } @@ -60,7 +60,7 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, is) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, is) 2 * is.read(_, _, _) 0 * _ } @@ -77,7 +77,7 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, reader) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, reader) 0 * _ } @@ -93,7 +93,7 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: result != null - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, bytes) + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, bytes) 0 * _ } @@ -108,7 +108,7 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: parser != null - 1 * propagationModule.taintObjectIfRangeTainted(_ as JsonParser, bytes, 0, 2, false, VulnerabilityMarks.NOT_MARKED) + 1 * propagationModule.taintObjectIfRangeTainted(_, _ as JsonParser, bytes, 0, 2, false, VulnerabilityMarks.NOT_MARKED) 0 * _ } @@ -127,8 +127,8 @@ class Json2FactoryInstrumentationTest extends AgentTestRunner { then: parser != null json == [key: 'value'] - 1 * propagationModule.taintObjectIfTainted(_ as JsonParser, url) - 1 * propagationModule.findSource(_ as JsonParser) >> null + 1 * propagationModule.taintObjectIfTainted(_, _ as JsonParser, url) + 1 * propagationModule.findSource(_, _ as JsonParser) >> null 1 * ssrfModule.onURLConnection(url) 0 * _ } diff --git a/dd-java-agent/instrumentation/jackson-core/src/test/groovy/JsonParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jackson-core/src/test/groovy/JsonParserInstrumentationTest.groovy index 236d109970b..d7e619ea7ff 100644 --- a/dd-java-agent/instrumentation/jackson-core/src/test/groovy/JsonParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jackson-core/src/test/groovy/JsonParserInstrumentationTest.groovy @@ -2,8 +2,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source import groovy.json.JsonOutput import java.nio.charset.Charset @@ -32,11 +32,11 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root_value', source.origin, _, JSON_STRING) - 1 * module.taintString(_, 'array_0', source.origin, _, JSON_STRING) - 1 * module.taintString(_, 'array_1', source.origin, _, JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root_value', source.origin, _, JSON_STRING) + 1 * module.taintObject(_, 'array_0', source.origin, _, JSON_STRING) + 1 * module.taintObject(_, 'array_1', source.origin, _, JSON_STRING) 0 * _ } @@ -55,11 +55,11 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> source - 1 * module.taintString(_, 'root_value', source.origin, _, JSON_STRING) - 1 * module.taintString(_, 'array_0', source.origin, _, JSON_STRING) - 1 * module.taintString(_, 'array_1', source.origin, _, JSON_STRING) + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> source + 1 * module.taintObject(_, 'root_value', source.origin, _, JSON_STRING) + 1 * module.taintObject(_, 'array_0', source.origin, _, JSON_STRING) + 1 * module.taintObject(_, 'array_1', source.origin, _, JSON_STRING) 0 * _ } @@ -76,8 +76,8 @@ class JsonParserInstrumentationTest extends AgentTestRunner { then: JsonOutput.toJson(taintedResult) == JSON_STRING - _ * module.taintObjectIfTainted(_, _) - _ * module.findSource(_) >> null + _ * module.taintObjectIfTainted(_, _, _) + _ * module.findSource(_, _) >> null 0 * _ where: @@ -88,9 +88,24 @@ class JsonParserInstrumentationTest extends AgentTestRunner { return [JSON_STRING, new ByteArrayInputStream(JSON_STRING.getBytes(Charset.defaultCharset()))] } - private static class SourceImpl implements Taintable.Source { + private static class SourceImpl implements Source { byte origin String name String value + + @Override + Source attachValue(Object newValue) { + return new SourceImpl(origin: origin, name: name, value: newValue as String) + } + + @Override + boolean isReference() { + return false + } + + @Override + Object getRawValue() { + return value + } } } diff --git a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/ByteBufferCallSite.java b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/ByteBufferCallSite.java index f3ae16c4b9e..87deb6ddce8 100644 --- a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/ByteBufferCallSite.java +++ b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/ByteBufferCallSite.java @@ -4,9 +4,11 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.nio.ByteBuffer; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -26,7 +28,8 @@ public static ByteBuffer afterWrap( return result; } try { - module.taintObjectIfTainted(result, bytes, true, NOT_MARKED); // keep ranges + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, bytes, true, NOT_MARKED); // keep ranges } catch (final Throwable e) { module.onUnexpectedException("beforeConstructor threw", e); } @@ -44,7 +47,8 @@ public static byte[] afterArray( return bytes; } try { - module.taintObjectIfTainted(bytes, buffer, true, NOT_MARKED); // keep ranges + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, bytes, buffer, true, NOT_MARKED); // keep ranges } catch (final Throwable e) { module.onUnexpectedException("afterArray threw", e); } diff --git a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamInstrumentation.java b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamInstrumentation.java index 32e7054fc69..688c6ab9cad 100644 --- a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamInstrumentation.java +++ b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamInstrumentation.java @@ -8,9 +8,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -57,7 +59,8 @@ public static void onExit( final PropagationModule module = InstrumentationBridge.PROPAGATION; try { if (module != null) { - module.taintObjectIfTainted(self, param); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, self, param); } } catch (final Throwable e) { module.onUnexpectedException("InputStreamAdvice onExit threw", e); diff --git a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamReaderCallSite.java b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamReaderCallSite.java index e78db178697..b16aa70e0cb 100644 --- a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamReaderCallSite.java +++ b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/InputStreamReaderCallSite.java @@ -2,9 +2,11 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStreamReader; import javax.annotation.Nonnull; @@ -20,7 +22,8 @@ public static InputStreamReader afterInit( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintObjectIfTainted(result, params[0]); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, params[0]); } catch (final Throwable e) { module.onUnexpectedException("afterInit threw", e); } diff --git a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/StringReaderCallSite.java b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/StringReaderCallSite.java index 0a81291e2f7..5e632db91f9 100644 --- a/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/StringReaderCallSite.java +++ b/dd-java-agent/instrumentation/java-io/src/main/java/datadog/trace/instrumentation/java/lang/StringReaderCallSite.java @@ -2,9 +2,11 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.StringReader; import javax.annotation.Nonnull; @@ -19,7 +21,8 @@ public static StringReader afterInit( final PropagationModule propagationModule = InstrumentationBridge.PROPAGATION; if (propagationModule != null) { try { - propagationModule.taintObjectIfTainted(result, params[0]); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagationModule.taintObjectIfTainted(to, result, params[0]); } catch (Throwable e) { propagationModule.onUnexpectedException("afterInit threw", e); } diff --git a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/ByteBufferTest.groovy b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/ByteBufferTest.groovy index ff65048116c..0cfb492ba47 100644 --- a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/ByteBufferTest.groovy +++ b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/ByteBufferTest.groovy @@ -25,7 +25,7 @@ class ByteBufferTest extends AgentTestRunner { TestByteBufferSuite.wrap(message) then: - 1 * module.taintObjectIfTainted(_ as ByteBuffer, message, true, VulnerabilityMarks.NOT_MARKED) + 1 * module.taintObjectIfTainted(_, _ as ByteBuffer, message, true, VulnerabilityMarks.NOT_MARKED) } void 'test array method'() { @@ -39,6 +39,6 @@ class ByteBufferTest extends AgentTestRunner { then: result == message.array() - 1 * module.taintObjectIfTainted(_ as byte[], message, true, VulnerabilityMarks.NOT_MARKED) + 1 * module.taintObjectIfTainted(_, _ as byte[], message, true, VulnerabilityMarks.NOT_MARKED) } } diff --git a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamInstrumentationTest.groovy b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamInstrumentationTest.groovy index 2c348f5913f..b71bd383c45 100644 --- a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamInstrumentationTest.groovy @@ -23,6 +23,6 @@ class InputStreamInstrumentationTest extends AgentTestRunner { TestInputStreamSuite.pushbackInputStreamFromIS(is) then: - (1.._) * propagationModule.taintObjectIfTainted(_ as InputStream, is) + (1.._) * propagationModule.taintObjectIfTainted(_, _ as InputStream, is) } } diff --git a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamReaderCallSiteTest.groovy b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamReaderCallSiteTest.groovy index 7b5a3e568ff..8373067cf89 100644 --- a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamReaderCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/InputStreamReaderCallSiteTest.groovy @@ -17,7 +17,7 @@ class InputStreamReaderCallSiteTest extends BaseIoCallSiteTest{ TestInputStreamReaderSuite.init(new ByteArrayInputStream("test".getBytes()), Charset.defaultCharset()) then: - 1 * iastModule.taintObjectIfTainted(_ as InputStreamReader, _ as InputStream) + 1 * iastModule.taintObjectIfTainted(_, _ as InputStreamReader, _ as InputStream) 0 * _ } } diff --git a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/StringReaderCallSiteTest.groovy b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/StringReaderCallSiteTest.groovy index e106adfb98f..742612052aa 100644 --- a/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/StringReaderCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/java-io/src/test/groovy/datadog/trace/instrumentation/java/io/StringReaderCallSiteTest.groovy @@ -17,7 +17,7 @@ class StringReaderCallSiteTest extends BaseIoCallSiteTest { TestStringReaderSuite.init(input) then: - 1 * iastModule.taintObjectIfTainted(_ as StringReader, input) + 1 * iastModule.taintObjectIfTainted(_, _ as StringReader, input) } void 'test super call to StringReader.'() { @@ -32,6 +32,7 @@ class StringReaderCallSiteTest extends BaseIoCallSiteTest { then: // new StringReader 3 * iastModule.taintObjectIfTainted( + _, { it -> !(it instanceof TestCustomStringReader) }, { String it -> it.startsWith("New") } @@ -39,6 +40,7 @@ class StringReaderCallSiteTest extends BaseIoCallSiteTest { // super(...) 1 * iastModule.taintObjectIfTainted( + _, { it instanceof TestCustomStringReader }, { String it -> it.startsWith("Super") }) } diff --git a/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSite.java b/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSite.java index 2cca8fccd62..2a3123454f7 100644 --- a/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSite.java +++ b/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSite.java @@ -4,10 +4,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.CodecModule; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.nio.charset.Charset; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -148,7 +150,8 @@ public static char[] afterToCharArray( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintObjectIfTainted(result, self, true, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self, true, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("afterToCharArray threw", e); } diff --git a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSiteForkedTest.groovy b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSiteForkedTest.groovy index 08d8a48122b..04e16292688 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSiteForkedTest.groovy +++ b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringFullDetectionCallSiteForkedTest.groovy @@ -71,7 +71,7 @@ class StringFullDetectionCallSiteForkedTest extends AgentTestRunner { then: result != null && result.length > 0 - 1 * module.taintObjectIfTainted(_ as char[], string, true, VulnerabilityMarks.NOT_MARKED) + 1 * module.taintObjectIfTainted(_, _ as char[], string, true, VulnerabilityMarks.NOT_MARKED) 0 * _ } diff --git a/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URICallSite.java b/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URICallSite.java index adab398831a..df9d7d140eb 100644 --- a/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URICallSite.java +++ b/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URICallSite.java @@ -4,10 +4,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.CodecModule; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.net.URI; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -66,7 +68,8 @@ public static String afterToString( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, url, true, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, true, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toString threw", e); } @@ -82,7 +85,8 @@ public static String afterToASCIIString( if (module != null && result != null) { try { boolean keepRanges = url.toString().equals(result); - module.taintStringIfTainted(result, url, keepRanges, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, keepRanges, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toASCIIString threw", e); } @@ -98,7 +102,8 @@ public static URI afterNormalize( if (module != null && result != null) { try { boolean keepRanges = url.toString().equals(result.toString()); - module.taintObjectIfTainted(result, url, keepRanges, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, keepRanges, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toString threw", e); } diff --git a/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URLCallSite.java b/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URLCallSite.java index bf7bb6b0cf1..10b0cd4c871 100644 --- a/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URLCallSite.java +++ b/dd-java-agent/instrumentation/java-net/src/main/java/datadog/trace/instrumentation/java/net/URLCallSite.java @@ -4,10 +4,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.CodecModule; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.net.URI; import java.net.URL; import javax.annotation.Nonnull; @@ -52,7 +54,8 @@ public static String afterToString( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null && result != null) { try { - module.taintStringIfTainted(result, url, true, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, true, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toString threw", e); } @@ -69,7 +72,8 @@ public static String afterToExternalForm( if (module != null && result != null) { try { boolean keepRanges = url.toString().equals(result); - module.taintStringIfTainted(result, url, keepRanges, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, keepRanges, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toExternalForm threw", e); } @@ -85,7 +89,8 @@ public static URI afterToURI(@CallSite.This final URL url, @CallSite.Return fina if (module != null && result != null) { try { boolean keepRanges = url.toString().equals(result.toString()); - module.taintObjectIfTainted(result, url, keepRanges, NOT_MARKED); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, url, keepRanges, NOT_MARKED); } catch (final Throwable e) { module.onUnexpectedException("After toURI threw", e); } diff --git a/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URICallSIteTest.groovy b/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URICallSIteTest.groovy index 7ba0764dbd6..965c4b3a552 100644 --- a/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URICallSIteTest.groovy +++ b/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URICallSIteTest.groovy @@ -60,14 +60,14 @@ class URICallSIteTest extends AgentTestRunner { TestURICallSiteSuite.&"$method".call(args as Object[]) then: - 1 * module."taint${target}IfTainted"(_, _ as URI, keepRanges, _) + 1 * module.taintObjectIfTainted(_, _, _ as URI, keepRanges, _) where: - method | target | args | keepRanges - 'normalize' | 'Object' | [new URI('http://test.com/index?name=value#fragment')] | true - 'normalize' | 'Object' | [new URI('http://test.com/test/../index?name=value#fragment')] | false - 'toASCIIString' | 'String' | [new URI('http://test.com/index?name=value#fragment')] | true - 'toASCIIString' | 'String' | [new URI('http://test.com/æ¼¢/index?name=value#fragment')] | false - 'toString' | 'String' | [new URI('http://test.com/index?name=value#fragment')] | true + method | args | keepRanges + 'normalize' | [new URI('http://test.com/index?name=value#fragment')] | true + 'normalize' | [new URI('http://test.com/test/../index?name=value#fragment')] | false + 'toASCIIString' | [new URI('http://test.com/index?name=value#fragment')] | true + 'toASCIIString' | [new URI('http://test.com/æ¼¢/index?name=value#fragment')] | false + 'toString' | [new URI('http://test.com/index?name=value#fragment')] | true } } diff --git a/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URLCallSiteTest.groovy b/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URLCallSiteTest.groovy index 002bd2f7b86..9ff1a60d285 100644 --- a/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URLCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/java-net/src/test/groovy/datadog/trace/instrumentation/java/net/URLCallSiteTest.groovy @@ -44,13 +44,13 @@ class URLCallSiteTest extends AgentTestRunner { TestURLCallSiteSuite.&"$method".call(args as Object[]) then: - 1 * module."taint${target}IfTainted"(_, _ as URL, keepRanges, _) + 1 * module.taintObjectIfTainted(_, _, _ as URL, keepRanges, _) where: - method | target | args | keepRanges - 'toURI' | 'Object' | [new URL('http://test.com/index?name=value#fragment')] | true - 'toExternalForm' | 'String' | [new URL('http://test.com/index?name=value#fragment')] | true - 'toString' | 'String' | [new URL('http://test.com/index?name=value#fragment')] | true + method | args | keepRanges + 'toURI' | [new URL('http://test.com/index?name=value#fragment')] | true + 'toExternalForm' | [new URL('http://test.com/index?name=value#fragment')] | true + 'toString' | [new URL('http://test.com/index?name=value#fragment')] | true } protected URLStreamHandler dummyStreamHandler() { diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/AbstractStringReaderInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/AbstractStringReaderInstrumentation.java index 8c71bf95455..f04e42b457c 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/AbstractStringReaderInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/AbstractStringReaderInstrumentation.java @@ -5,17 +5,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -41,14 +38,11 @@ public String[] knownMatchingTypes() { }; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class FromStringAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Argument(0) final String param, - @Advice.Return Object result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String param, @Advice.Return Object result) { if (!(result instanceof String)) { return; } @@ -56,8 +50,8 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, (String) result, param); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, param); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ContainerRequestInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ContainerRequestInstrumentation.java index 0c84b867020..6fd67118308 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ContainerRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ContainerRequestInstrumentation.java @@ -5,17 +5,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -46,14 +43,10 @@ public String[] helperClassNames() { }; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class SetPropertyAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - public static void onExit( - @Advice.Argument(0) String name, - @Advice.Argument(1) Object value, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Argument(0) String name, @Advice.Argument(1) Object value) { if (!"jersey.config.server.representation.decoded.form".equals(name) && !"jersey.config.server.representation.form".equals(name)) { @@ -65,11 +58,11 @@ public static void onExit( return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (prop.isTainted(ctx, value)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (prop.isTainted(to, value)) { return; } - prop.taintObject(ctx, value, SourceTypes.REQUEST_BODY); + prop.taintObject(to, value, SourceTypes.REQUEST_BODY); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/CookieInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/CookieInstrumentation.java index 5e95ec601a3..71fc08c724a 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/CookieInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/CookieInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -42,36 +39,30 @@ public String[] knownMatchingTypes() { return new String[] {"jakarta.ws.rs.core.Cookie", "javax.ws.rs.core.Cookie"}; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class InstrumenterAdviceGetName { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_NAME) - public static void onExit( - @Advice.Return String cookieName, - @Advice.This Object self, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return String cookieName, @Advice.This Object self) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted( - ctx, cookieName, self, SourceTypes.REQUEST_COOKIE_NAME, cookieName); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, cookieName, self, SourceTypes.REQUEST_COOKIE_NAME, cookieName); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetValueAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) public static void onExit( @Advice.Return String cookieValue, @Advice.FieldValue("name") String name, - @Advice.This Object self, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This Object self) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, cookieValue, self, SourceTypes.REQUEST_COOKIE_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, cookieValue, self, SourceTypes.REQUEST_COOKIE_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/FormInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/FormInstrumentation.java index 291d0cb364d..560cf47bebf 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/FormInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/FormInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -48,14 +45,11 @@ public String[] helperClassNames() { }; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class AsMapAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Return Map> form, - @Advice.This Object self, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Map> form, @Advice.This Object self) { if (form == null || form.isEmpty()) { return; } @@ -63,15 +57,15 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!module.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!module.isTainted(to, self)) { return; } - if (module.isTainted(ctx, form)) { + if (module.isTainted(to, form)) { return; } - module.taintObject(ctx, form, SourceTypes.REQUEST_PARAMETER_VALUE); - taintMultiValuedMap(ctx, module, SourceTypes.REQUEST_PARAMETER_VALUE, form); + module.taintObject(to, form, SourceTypes.REQUEST_PARAMETER_VALUE); + taintMultiValuedMap(to, module, SourceTypes.REQUEST_PARAMETER_VALUE, form); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/InboundMessageContextInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/InboundMessageContextInstrumentation.java index 56b346d36d3..c32658fe207 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/InboundMessageContextInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/InboundMessageContextInstrumentation.java @@ -9,17 +9,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import java.util.List; import java.util.Map; @@ -75,13 +72,10 @@ public static void onExit() { } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void onExit( - @Advice.Return Map> headers, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return Map> headers) { // ignore internal calls populating headers if (CallDepthThreadLocalMap.getCallDepth(InboundMessageContext.class) != 0) { return; @@ -94,21 +88,19 @@ public static void onExit( if (prop == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (prop.isTainted(ctx, headers)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (prop.isTainted(to, headers)) { return; } - prop.taintObject(headers, SourceTypes.REQUEST_HEADER_VALUE); - taintMultiValuedMap(ctx, prop, SourceTypes.REQUEST_HEADER_VALUE, headers); + prop.taintObject(to, headers, SourceTypes.REQUEST_HEADER_VALUE); + taintMultiValuedMap(to, prop, SourceTypes.REQUEST_HEADER_VALUE, headers); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class CookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onExit( - @Advice.Return Map cookies, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return Map cookies) { if (cookies == null || cookies.isEmpty()) { return; } @@ -116,19 +108,17 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Map.Entry entry : cookies.entrySet()) { - module.taintObject(ctx, entry.getValue(), SourceTypes.REQUEST_COOKIE_VALUE, entry.getKey()); + module.taintObject(to, entry.getValue(), SourceTypes.REQUEST_COOKIE_VALUE, entry.getKey()); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ReadEntityAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) - public static void onExit( - @Advice.Return Object result, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return Object result) { if (result == null) { return; } @@ -136,13 +126,13 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (module.isTainted(ctx, result)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (module.isTainted(to, result)) { return; } - module.taintObject(ctx, result, SourceTypes.REQUEST_BODY); + module.taintObject(to, result, SourceTypes.REQUEST_BODY); if (result instanceof Map) { - taintMap(ctx, module, SourceTypes.REQUEST_PARAMETER_VALUE, (Map) result); + taintMap(to, module, SourceTypes.REQUEST_PARAMETER_VALUE, (Map) result); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/JerseyTaintHelper.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/JerseyTaintHelper.java index 2c7d8866428..634eb170cd5 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/JerseyTaintHelper.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/JerseyTaintHelper.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.jersey; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; @@ -11,7 +11,7 @@ public abstract class JerseyTaintHelper { private JerseyTaintHelper() {} public static void taintMultiValuedMap( - final IastContext ctx, + final TaintedObjects to, final PropagationModule module, final byte type, final Map> target) { @@ -20,16 +20,16 @@ public static void taintMultiValuedMap( for (Map.Entry> entry : target.entrySet()) { final String name = entry.getKey(); if (reportName) { - module.taintString(ctx, name, nameType, name); + module.taintObject(to, name, nameType, name); } for (String value : entry.getValue()) { - module.taintString(ctx, value, type, name); + module.taintObject(to, value, type, name); } } } public static void taintMap( - final IastContext ctx, + final TaintedObjects to, final PropagationModule module, final byte type, final Map target) { @@ -40,15 +40,15 @@ public static void taintMap( if (key instanceof String) { final String name = (String) key; if (reportName) { - module.taintString(ctx, name, nameType, name); + module.taintObject(to, name, nameType, name); } final Object value = entry.getValue(); if (value instanceof String) { - module.taintString(ctx, (String) value, type, name); + module.taintObject(to, value, type, name); } else if (value instanceof List) { for (final Object item : (List) value) { if (item instanceof String) { - module.taintString(ctx, (String) item, type, name); + module.taintObject(to, item, type, name); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ReaderInterceptorExecutorInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ReaderInterceptorExecutorInstrumentation.java index 76509b9a85c..c33c8a9d937 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ReaderInterceptorExecutorInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/ReaderInterceptorExecutorInstrumentation.java @@ -4,16 +4,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import net.bytebuddy.asm.Advice; @@ -37,15 +34,13 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$InstrumenterAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class InstrumenterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - static void after( - @Advice.Return final InputStream inputStream, @ActiveRequestContext RequestContext reqCtx) { + static void after(@Advice.Return final InputStream inputStream) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, inputStream, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, inputStream, SourceTypes.REQUEST_BODY); } } } diff --git a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/UriRoutingContextInstrumentation.java b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/UriRoutingContextInstrumentation.java index 1924d3e5e32..a50e4580b14 100644 --- a/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/UriRoutingContextInstrumentation.java +++ b/dd-java-agent/instrumentation/jersey/src/main/java/datadog/trace/instrumentation/jersey/UriRoutingContextInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -52,13 +49,10 @@ public String[] helperClassNames() { }; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetPathParametersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PATH_PARAMETER) - public static void onExit( - @Advice.Return Map> pathParams, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return Map> pathParams) { if (pathParams == null || pathParams.isEmpty()) { return; } @@ -66,22 +60,19 @@ public static void onExit( if (prop == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (prop.isTainted(ctx, pathParams)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (prop.isTainted(to, pathParams)) { return; } - prop.taintObject(ctx, pathParams, SourceTypes.REQUEST_PATH_PARAMETER); - taintMultiValuedMap(ctx, prop, SourceTypes.REQUEST_PATH_PARAMETER, pathParams); + prop.taintObject(to, pathParams, SourceTypes.REQUEST_PATH_PARAMETER); + taintMultiValuedMap(to, prop, SourceTypes.REQUEST_PATH_PARAMETER, pathParams); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetQueryParametersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - public static void onExit( - @Advice.Return Map> queryParams, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return Map> queryParams) { if (queryParams == null || queryParams.isEmpty()) { return; } @@ -89,12 +80,12 @@ public static void onExit( if (prop == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (prop.isTainted(ctx, queryParams)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (prop.isTainted(to, queryParams)) { return; } - prop.taintObject(ctx, queryParams, SourceTypes.REQUEST_PARAMETER_VALUE); - taintMultiValuedMap(ctx, prop, SourceTypes.REQUEST_PARAMETER_VALUE, queryParams); + prop.taintObject(to, queryParams, SourceTypes.REQUEST_PARAMETER_VALUE); + taintMultiValuedMap(to, prop, SourceTypes.REQUEST_PARAMETER_VALUE, queryParams); } } } diff --git a/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JSONObjectUtilsInstrumentation.java b/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JSONObjectUtilsInstrumentation.java index 4c2ea64527f..32fe11790b6 100644 --- a/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JSONObjectUtilsInstrumentation.java +++ b/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JSONObjectUtilsInstrumentation.java @@ -5,17 +5,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -39,24 +36,22 @@ public String instrumentedType() { return "com.nimbusds.jose.util.JSONObjectUtils"; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class InstrumenterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void onEnter( - @Advice.Return Map map, @ActiveRequestContext RequestContext reqCtx) { + public static void onEnter(@Advice.Return Map map) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (Map.Entry entry : map.entrySet()) { final String name = entry.getKey(); final Object value = entry.getValue(); if (value instanceof String) { // TODO: We could represent this source more accurately, perhaps tracking the original // source, or using a special name. - module.taintString(ctx, (String) value, SourceTypes.REQUEST_HEADER_VALUE, name); + module.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JWTParserInstrumentation.java b/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JWTParserInstrumentation.java index 5fcd4340c09..421306f5839 100644 --- a/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JWTParserInstrumentation.java +++ b/dd-java-agent/instrumentation/jose-jwt/src/main/java/datadog/trace/instrumentation/josejwt/JWTParserInstrumentation.java @@ -5,17 +5,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -38,20 +35,18 @@ public String instrumentedType() { return "com.auth0.jwt.impl.JWTParser"; } - @RequiresRequestContext(RequestContextSlot.IAST) public static class InstrumenterAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void onEnter( - @Advice.Argument(0) String json, @ActiveRequestContext RequestContext reqCtx) { + public static void onEnter(@Advice.Argument(0) String json) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { // TODO: We could represent this source more accurately, perhaps tracking the original // source, or using a special name. - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, json, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, json, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/jose-jwt/src/test/groovy/JWTParserInstrumentationTest.groovy b/dd-java-agent/instrumentation/jose-jwt/src/test/groovy/JWTParserInstrumentationTest.groovy index 2d649db0aa2..70edc64b325 100644 --- a/dd-java-agent/instrumentation/jose-jwt/src/test/groovy/JWTParserInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jose-jwt/src/test/groovy/JWTParserInstrumentationTest.groovy @@ -3,12 +3,14 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext class JWTParserInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -16,7 +18,10 @@ class JWTParserInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'oauth jwt parser'() { @@ -29,7 +34,7 @@ class JWTParserInstrumentationTest extends AgentTestRunner { runUnderIastTrace { new com.auth0.jwt.impl.JWTParser().parsePayload(payload) } then: - 1 * propagationModule.taintString(iastCtx, payload, SourceTypes.REQUEST_HEADER_VALUE) + 1 * propagationModule.taintObject(to, payload, SourceTypes.REQUEST_HEADER_VALUE) 0 * _ } @@ -43,11 +48,11 @@ class JWTParserInstrumentationTest extends AgentTestRunner { runUnderIastTrace { com.nimbusds.jose.util.JSONObjectUtils.parse(json) } then: - 1 * propagationModule.taintString(iastCtx, 'http://foobar.com', SourceTypes.REQUEST_HEADER_VALUE, 'iss') - 1 * propagationModule.taintString(iastCtx, 'foo', SourceTypes.REQUEST_HEADER_VALUE, 'sub') - 1 * propagationModule.taintString(iastCtx, 'foobar', SourceTypes.REQUEST_HEADER_VALUE, 'aud') - 1 * propagationModule.taintString(iastCtx, 'Mr Foo Bar', SourceTypes.REQUEST_HEADER_VALUE, 'name') - 1 * propagationModule.taintString(iastCtx, 'read', SourceTypes.REQUEST_HEADER_VALUE, 'scope') + 1 * propagationModule.taintObject(to, 'http://foobar.com', SourceTypes.REQUEST_HEADER_VALUE, 'iss') + 1 * propagationModule.taintObject(to, 'foo', SourceTypes.REQUEST_HEADER_VALUE, 'sub') + 1 * propagationModule.taintObject(to, 'foobar', SourceTypes.REQUEST_HEADER_VALUE, 'aud') + 1 * propagationModule.taintObject(to, 'Mr Foo Bar', SourceTypes.REQUEST_HEADER_VALUE, 'name') + 1 * propagationModule.taintObject(to, 'read', SourceTypes.REQUEST_HEADER_VALUE, 'scope') 0 * _ } diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaDeserializerInstrumentation.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaDeserializerInstrumentation.java index 269a5118f16..543e5e6594f 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaDeserializerInstrumentation.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaDeserializerInstrumentation.java @@ -10,9 +10,9 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.InstrumentationContext; import java.nio.ByteBuffer; @@ -110,20 +110,20 @@ public static class Deserialize2Advice { public static void deserialize( @Advice.This final Deserializer deserializer, @Advice.Argument(1) byte[] data, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - ctx = KafkaIastHelper.beforeDeserialize(store, deserializer, data); + to = KafkaIastHelper.beforeDeserialize(store, deserializer, data); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) public static void afterDeserialize( @Advice.This final Deserializer deserializer, @Advice.Return Object result, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - KafkaIastHelper.afterDeserialize(ctx, store, deserializer, result); + KafkaIastHelper.afterDeserialize(to, store, deserializer, result); } } @@ -135,20 +135,20 @@ public static class Deserialize3Advice { public static void deserialize( @Advice.This final Deserializer deserializer, @Advice.Argument(2) byte[] data, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - ctx = KafkaIastHelper.beforeDeserialize(store, deserializer, data); + to = KafkaIastHelper.beforeDeserialize(store, deserializer, data); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) public static void afterDeserialize( @Advice.This final Deserializer deserializer, @Advice.Return Object result, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - KafkaIastHelper.afterDeserialize(ctx, store, deserializer, result); + KafkaIastHelper.afterDeserialize(to, store, deserializer, result); } } @@ -160,20 +160,20 @@ public static class DeserializeByteBufferAdvice { public static void deserialize( @Advice.This final Deserializer deserializer, @Advice.Argument(2) ByteBuffer data, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - ctx = KafkaIastHelper.beforeDeserialize(store, deserializer, data); + to = KafkaIastHelper.beforeDeserialize(store, deserializer, data); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) public static void afterDeserialize( @Advice.This final Deserializer deserializer, @Advice.Return final Object result, - @Advice.Local("iastCtx") IastContext ctx) { + @Advice.Local("iastTo") TaintedObjects to) { final ContextStore store = InstrumentationContext.get(Deserializer.class, Boolean.class); - KafkaIastHelper.afterDeserialize(ctx, store, deserializer, result); + KafkaIastHelper.afterDeserialize(to, store, deserializer, result); } } } diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaIastHelper.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaIastHelper.java index 4063904a4d6..7721aede3a6 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaIastHelper.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaIastHelper.java @@ -6,6 +6,7 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.ContextStore; import java.nio.ByteBuffer; @@ -23,7 +24,7 @@ public static void configure( } } - public static IastContext beforeDeserialize( + public static TaintedObjects beforeDeserialize( final ContextStore store, final Deserializer deserializer, final Object data) { @@ -35,23 +36,19 @@ public static IastContext beforeDeserialize( if (module == null) { return null; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return null; } - if (module.isTainted(ctx, data)) { - return ctx; // prevent double tainting on reentrant calls + if (module.isTainted(to, data)) { + return to; // prevent double tainting on reentrant calls } final byte source = getSource(store, deserializer); - if (data instanceof String) { - module.taintString(ctx, (String) data, source); - } else { - module.taintObject(ctx, data, source); - } - return ctx; + module.taintObject(to, data, source); + return to; } - public static IastContext beforeDeserialize( + public static TaintedObjects beforeDeserialize( final ContextStore store, final Deserializer deserializer, final ByteBuffer data) { @@ -63,24 +60,24 @@ public static IastContext beforeDeserialize( if (module == null) { return null; } - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return null; } - if (module.isTainted(ctx, data)) { - return ctx; // prevent double tainting on reentrant calls + if (module.isTainted(to, data)) { + return to; // prevent double tainting on reentrant calls } final byte source = getSource(store, deserializer); int start = data.position(); if (data.hasArray()) { start += data.arrayOffset(); } - module.taintObjectRange(ctx, data, source, start, data.remaining()); - return ctx; + module.taintObjectRange(to, data, source, start, data.remaining()); + return to; } public static void afterDeserialize( - final IastContext ctx, + final TaintedObjects to, final ContextStore store, final Deserializer deserializer, final Object result) { @@ -93,11 +90,7 @@ public static void afterDeserialize( return; } final byte source = getSource(store, deserializer); - if (result instanceof String) { - module.taintString(ctx, (String) result, source); - } else { - module.taintObject(ctx, result, source); - } + module.taintObject(to, result, source); } private static byte getSource( diff --git a/dd-java-agent/instrumentation/netty-buffer-4/src/main/java/datadog/trace/instrumentation/netty40/buffer/ByteBufInputStreamInstrumentation.java b/dd-java-agent/instrumentation/netty-buffer-4/src/main/java/datadog/trace/instrumentation/netty40/buffer/ByteBufInputStreamInstrumentation.java index 74e71c0895e..49131b30823 100644 --- a/dd-java-agent/instrumentation/netty-buffer-4/src/main/java/datadog/trace/instrumentation/netty40/buffer/ByteBufInputStreamInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-buffer-4/src/main/java/datadog/trace/instrumentation/netty40/buffer/ByteBufInputStreamInstrumentation.java @@ -10,9 +10,11 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -54,7 +56,8 @@ public static void onExit( final PropagationModule module = InstrumentationBridge.PROPAGATION; try { if (module != null) { - module.taintObjectIfTainted(self, buffer); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, self, buffer); } } catch (final Throwable e) { module.onUnexpectedException("ByteBufInputStream ctor threw", e); diff --git a/dd-java-agent/instrumentation/okhttp-2/src/main/java/datadog/trace/instrumentation/okhttp2/IastHttpUrlInstrumentation.java b/dd-java-agent/instrumentation/okhttp-2/src/main/java/datadog/trace/instrumentation/okhttp2/IastHttpUrlInstrumentation.java index cba9a7f35de..c91065e76dc 100644 --- a/dd-java-agent/instrumentation/okhttp-2/src/main/java/datadog/trace/instrumentation/okhttp2/IastHttpUrlInstrumentation.java +++ b/dd-java-agent/instrumentation/okhttp-2/src/main/java/datadog/trace/instrumentation/okhttp2/IastHttpUrlInstrumentation.java @@ -10,9 +10,11 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.net.URL; import net.bytebuddy.asm.Advice; @@ -77,7 +79,8 @@ public static void onParse( @Advice.Argument(0) final Object argument, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(result, argument); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, argument); } } } @@ -90,7 +93,8 @@ public static void onPropagation( @Advice.This final Object self, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self); } } } diff --git a/dd-java-agent/instrumentation/okhttp-2/src/test/groovy/IastOkHttp2InstrumentationTest.groovy b/dd-java-agent/instrumentation/okhttp-2/src/test/groovy/IastOkHttp2InstrumentationTest.groovy index 42d4909eb17..14b32dd167a 100644 --- a/dd-java-agent/instrumentation/okhttp-2/src/test/groovy/IastOkHttp2InstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/okhttp-2/src/test/groovy/IastOkHttp2InstrumentationTest.groovy @@ -69,8 +69,7 @@ class IastOkHttp2InstrumentationTest extends AgentTestRunner { } final propagation = Mock(PropagationModule) { - taintStringIfTainted(*_) >> { taint(it[0], [it[1]]) } - taintObjectIfTainted(*_) >> { taint(it[0], [it[1]]) } + taintObjectIfTainted(*_) >> { taint(it[1], [it[2]]) } } InstrumentationBridge.registerIastModule(propagation) diff --git a/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/IastHttpUrlInstrumentation.java b/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/IastHttpUrlInstrumentation.java index de896c73133..452d66a621b 100644 --- a/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/IastHttpUrlInstrumentation.java +++ b/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/IastHttpUrlInstrumentation.java @@ -10,9 +10,11 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.net.URL; import net.bytebuddy.asm.Advice; @@ -77,7 +79,8 @@ public static void onParse( @Advice.Argument(0) final Object arg, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(result, arg); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, arg); } } } diff --git a/dd-java-agent/instrumentation/okhttp-3/src/test/groovy/IastOkHttp3InstrumentationTest.groovy b/dd-java-agent/instrumentation/okhttp-3/src/test/groovy/IastOkHttp3InstrumentationTest.groovy index 321d04cb743..3a352458c5d 100644 --- a/dd-java-agent/instrumentation/okhttp-3/src/test/groovy/IastOkHttp3InstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/okhttp-3/src/test/groovy/IastOkHttp3InstrumentationTest.groovy @@ -74,8 +74,7 @@ class IastOkHttp3InstrumentationTest extends AgentTestRunner { } final propagation = Mock(PropagationModule) { - taintStringIfTainted(*_) >> { taint(it[0], [it[1]]) } - taintObjectIfTainted(*_) >> { taint(it[0], [it[1]]) } + taintObjectIfTainted(*_) >> { taint(it[1], [it[2]]) } } InstrumentationBridge.registerIastModule(propagation) diff --git a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONArrayInstrumentation.java b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONArrayInstrumentation.java index dcbe22da820..60dbd0b1747 100644 --- a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONArrayInstrumentation.java +++ b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONArrayInstrumentation.java @@ -10,9 +10,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.json.JSONArray; import org.json.JSONObject; @@ -53,7 +55,8 @@ public static class ConstructorAdvice { public static void afterInit(@Advice.This Object self, @Advice.Argument(0) final Object input) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && input != null) { - iastModule.taintObjectIfTainted(self, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, self, input); } } } @@ -69,11 +72,8 @@ public static void afterMethod(@Advice.This Object self, @Advice.Return final Ob } final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null) { - if (isString) { - iastModule.taintStringIfTainted((String) result, self); - } else { - iastModule.taintObjectIfTainted(result, self); - } + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, result, self); } } } @@ -89,11 +89,8 @@ public static void afterMethod(@Advice.This Object self, @Advice.Return final Ob } final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null) { - if (isString) { - iastModule.taintStringIfTainted((String) result, self); - } else { - iastModule.taintObjectIfTainted(result, self); - } + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, result, self); } } } diff --git a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONCookieInstrumentation.java b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONCookieInstrumentation.java index 4946459c8bf..805da9715a0 100644 --- a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONCookieInstrumentation.java +++ b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONCookieInstrumentation.java @@ -6,9 +6,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -38,7 +40,8 @@ public static void onExit( @Advice.Return Object retValue, @Advice.Argument(0) final String input) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && input != null) { - iastModule.taintObjectIfTainted(retValue, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, retValue, input); } } } diff --git a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONObjectInstrumentation.java b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONObjectInstrumentation.java index b7261b6a9b7..f9251ce330a 100644 --- a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONObjectInstrumentation.java +++ b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONObjectInstrumentation.java @@ -10,9 +10,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.json.JSONArray; import org.json.JSONObject; @@ -55,7 +57,8 @@ public static class ConstructorAdvice { public static void afterInit(@Advice.This Object self, @Advice.Argument(0) final Object input) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && input != null) { - iastModule.taintObjectIfTainted(self, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, self, input); } } } @@ -71,11 +74,8 @@ public static void afterMethod(@Advice.This Object self, @Advice.Return final Ob } final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null) { - if (isString) { - iastModule.taintStringIfTainted((String) result, self); - } else { - iastModule.taintObjectIfTainted(result, self); - } + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, result, self); } } } @@ -91,11 +91,8 @@ public static void afterMethod(@Advice.This Object self, @Advice.Return final Ob } final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null) { - if (isString) { - iastModule.taintStringIfTainted((String) result, self); - } else { - iastModule.taintObjectIfTainted(result, self); - } + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, result, self); } } } diff --git a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONTokenerInstrumentation.java b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONTokenerInstrumentation.java index 09539795ab6..6b0268414d0 100644 --- a/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONTokenerInstrumentation.java +++ b/dd-java-agent/instrumentation/org-json/src/main/java/datadog/trace/instrumentation/json/JSONTokenerInstrumentation.java @@ -6,9 +6,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -37,7 +39,8 @@ public static class ConstructorAdvice { public static void afterInit(@Advice.This Object self, @Advice.Argument(0) final Object input) { final PropagationModule iastModule = InstrumentationBridge.PROPAGATION; if (iastModule != null && input != null) { - iastModule.taintObjectIfTainted(self, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + iastModule.taintObjectIfTainted(to, self, input); } } } diff --git a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONArrayInstrumentationTest.groovy b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONArrayInstrumentationTest.groovy index d0a97012811..340169e50b5 100644 --- a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONArrayInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONArrayInstrumentationTest.groovy @@ -32,12 +32,12 @@ class JSONArrayInstrumentationTest extends AgentTestRunner { then: name == "File" - 1 * module.taintObjectIfTainted(_ as JSONObject, json) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONTokener) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONObject) - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) - 2 * module.taintObjectIfTainted(_ as JSONArray, _ as JSONObject) - 2 * module.taintStringIfTainted("File", _ as JSONArray) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, json) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONTokener) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) + 2 * module.taintObjectIfTainted(_, _ as JSONArray, _ as JSONObject) + 2 * module.taintObjectIfTainted(_, "File", _ as JSONArray) 0 * _ } @@ -61,12 +61,12 @@ class JSONArrayInstrumentationTest extends AgentTestRunner { then: name == "File" - 1 * module.taintObjectIfTainted(_ as JSONObject, json) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONTokener) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONObject) - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) - 2 * module.taintObjectIfTainted(_ as JSONArray, _ as JSONObject) - 1 * module.taintStringIfTainted("File", _ as JSONArray) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, json) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONTokener) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) + 2 * module.taintObjectIfTainted(_, _ as JSONArray, _ as JSONObject) + 1 * module.taintObjectIfTainted(_, "File", _ as JSONArray) 0 * _ } } diff --git a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONCookieInstrumentationTest.groovy b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONCookieInstrumentationTest.groovy index 004b7afdd22..936afff5626 100644 --- a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONCookieInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONCookieInstrumentationTest.groovy @@ -22,8 +22,8 @@ class JSONCookieInstrumentationTest extends AgentTestRunner { then: - 1 * module.taintObjectIfTainted(_ as JSONObject, cookie) - 1 * module.taintObjectIfTainted(_ as JSONTokener, cookie) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, cookie) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, cookie) 0 * _ } } diff --git a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONObjectInstrumentationTest.groovy b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONObjectInstrumentationTest.groovy index 49be03842d2..d9f0e75e301 100644 --- a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONObjectInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONObjectInstrumentationTest.groovy @@ -30,11 +30,11 @@ class JSONObjectInstrumentationTest extends AgentTestRunner { then: name == "nameTest" - 1 * module.taintObjectIfTainted(_ as JSONObject, json) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONTokener) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONObject) - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) - 2 * module.taintStringIfTainted("nameTest", _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, json) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONTokener) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) + 2 * module.taintObjectIfTainted(_, "nameTest", _ as JSONObject) 0 * _ } @@ -58,11 +58,11 @@ class JSONObjectInstrumentationTest extends AgentTestRunner { then: name == "nameTest" - 1 * module.taintObjectIfTainted(_ as JSONObject, json) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONTokener) - 2 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONObject) - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) - 1 * module.taintStringIfTainted("nameTest", _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, json) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONTokener) + 2 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) + 1 * module.taintObjectIfTainted(_, "nameTest", _ as JSONObject) 0 * _ } @@ -80,9 +80,9 @@ class JSONObjectInstrumentationTest extends AgentTestRunner { then: name == "nameTest" - 1 * module.taintObjectIfTainted(_ as JSONObject, _ as JSONTokener) - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) - 2 * module.taintStringIfTainted("nameTest", _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, _ as JSONTokener) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) + 2 * module.taintObjectIfTainted(_, "nameTest", _ as JSONObject) 0 * _ } @@ -100,8 +100,8 @@ class JSONObjectInstrumentationTest extends AgentTestRunner { jsonObject.get("name") then: - 1 * module.taintObjectIfTainted(_ as JSONObject, map) - 2 * module.taintStringIfTainted("nameTest", _ as JSONObject) + 1 * module.taintObjectIfTainted(_, _ as JSONObject, map) + 2 * module.taintObjectIfTainted(_, "nameTest", _ as JSONObject) 0 * _ } } diff --git a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONTokenerInstrumentationTest.groovy b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONTokenerInstrumentationTest.groovy index de8fa1da40c..fd8bf332203 100644 --- a/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONTokenerInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/org-json/src/test/groovy/JSONTokenerInstrumentationTest.groovy @@ -19,7 +19,7 @@ class JSONTokenerInstrumentationTest extends AgentTestRunner { new JSONTokener(json) then: - 1 * module.taintObjectIfTainted(_ as JSONTokener, json) + 1 * module.taintObjectIfTainted(_, _ as JSONTokener, json) 0 * _ } } diff --git a/dd-java-agent/instrumentation/owasp-esapi-2/src/main/java/datadog/trace/instrumentation/owasp/esapi/EncoderCallSite.java b/dd-java-agent/instrumentation/owasp-esapi-2/src/main/java/datadog/trace/instrumentation/owasp/esapi/EncoderCallSite.java index 06a6bbd59ae..53a5f710871 100644 --- a/dd-java-agent/instrumentation/owasp-esapi-2/src/main/java/datadog/trace/instrumentation/owasp/esapi/EncoderCallSite.java +++ b/dd-java-agent/instrumentation/owasp-esapi-2/src/main/java/datadog/trace/instrumentation/owasp/esapi/EncoderCallSite.java @@ -2,10 +2,12 @@ import datadog.trace.agent.tooling.csi.CallSite; import datadog.trace.api.iast.IastCallSites; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.VulnerabilityMarks; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.annotation.Nonnull; import org.owasp.esapi.Encoder; import org.owasp.esapi.codecs.Codec; @@ -22,7 +24,8 @@ public static String afterEncodeForHTML( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEncodeForHTML threw", e); } @@ -38,7 +41,8 @@ public static String afterCanonicalize1( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterCanonicalize1 threw", e); } @@ -56,7 +60,8 @@ public static String afterCanonicalize2( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterCanonicalize2 threw", e); } @@ -75,7 +80,8 @@ public static String afterCanonicalize3( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.XSS_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, input, false, VulnerabilityMarks.XSS_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterCanonicalize3 threw", e); } @@ -91,7 +97,9 @@ public static String afterEncodeForLDAP( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.LDAP_INJECTION_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, input, false, VulnerabilityMarks.LDAP_INJECTION_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEncodeForLDAP threw", e); } @@ -109,8 +117,9 @@ public static String afterEncodeForOS( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted( - result, input, false, VulnerabilityMarks.COMMAND_INJECTION_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, input, false, VulnerabilityMarks.COMMAND_INJECTION_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEncodeForOS threw", e); } @@ -128,7 +137,9 @@ public static String afterEncodeForSQL( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - module.taintStringIfTainted(result, input, false, VulnerabilityMarks.SQL_INJECTION_MARK); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, input, false, VulnerabilityMarks.SQL_INJECTION_MARK); } catch (final Throwable e) { module.onUnexpectedException("afterEncodeForSQL threw", e); } diff --git a/dd-java-agent/instrumentation/owasp-esapi-2/src/test/groovy/datadog/trace/instrumentation/owasp/esapi/EncoderCallSiteTest.groovy b/dd-java-agent/instrumentation/owasp-esapi-2/src/test/groovy/datadog/trace/instrumentation/owasp/esapi/EncoderCallSiteTest.groovy index c90ad8e96bc..d9392ed68dd 100644 --- a/dd-java-agent/instrumentation/owasp-esapi-2/src/test/groovy/datadog/trace/instrumentation/owasp/esapi/EncoderCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/owasp-esapi-2/src/test/groovy/datadog/trace/instrumentation/owasp/esapi/EncoderCallSiteTest.groovy @@ -25,7 +25,7 @@ class EncoderCallSiteTest extends AgentTestRunner { testSuite.&"$method".call(args) then: - 1 * module.taintStringIfTainted(_, _, false, mark) + 1 * module.taintObjectIfTainted(_, _, _, false, mark) 0 * module._ where: diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/CookieHeaderInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/CookieHeaderInstrumentation.java index a3103aa58f4..2d2e912c7eb 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/CookieHeaderInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/CookieHeaderInstrumentation.java @@ -8,17 +8,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.apache.pekko.http.javadsl.model.HttpHeader; import org.apache.pekko.http.scaladsl.model.headers.Cookie; @@ -54,20 +51,17 @@ public void methodAdvice(MethodTransformer transformer) { CookieHeaderInstrumentation.class.getName() + "$TaintAllCookiesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class TaintAllCookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) static void after( - @Advice.This HttpHeader cookie, - @Advice.Return Seq cookiePairs, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This HttpHeader cookie, @Advice.Return Seq cookiePairs) { PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || cookiePairs == null || cookiePairs.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!prop.isTainted(ctx, cookie)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!prop.isTainted(to, cookie)) { return; } @@ -75,8 +69,8 @@ static void after( while (iterator.hasNext()) { HttpCookiePair pair = iterator.next(); final String name = pair.name(), value = pair.value(); - prop.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HeaderNameCallSite.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HeaderNameCallSite.java index f0de41cd3da..e541f728f82 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HeaderNameCallSite.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HeaderNameCallSite.java @@ -7,7 +7,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import org.apache.pekko.http.javadsl.model.HttpHeader; /** @@ -29,11 +29,11 @@ public static String after(@CallSite.This HttpHeader header, @CallSite.Return St return result; } try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return result; } - module.taintStringIfTainted(ctx, result, header, SourceTypes.REQUEST_HEADER_NAME, result); + module.taintObjectIfTainted(to, result, header, SourceTypes.REQUEST_HEADER_NAME, result); } catch (final Throwable e) { module.onUnexpectedException("onHeaderNames threw", e); } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpHeaderSubclassesInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpHeaderSubclassesInstrumentation.java index 1e7c9d2a72e..719fb16185f 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpHeaderSubclassesInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpHeaderSubclassesInstrumentation.java @@ -9,16 +9,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -58,21 +55,17 @@ public void methodAdvice(MethodTransformer transformer) { HttpHeaderSubclassesInstrumentation.class.getName() + "$HttpHeaderSubclassesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class HttpHeaderSubclassesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation - static void onExit( - @Advice.This HttpHeader h, - @Advice.Return String retVal, - @ActiveRequestContext RequestContext reqCtx) { + static void onExit(@Advice.This HttpHeader h, @Advice.Return String retVal) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintStringIfTainted(ctx, retVal, h); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, retVal, h); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpRequestInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpRequestInstrumentation.java index db02dc8a6c3..e5828acaebb 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/HttpRequestInstrumentation.java @@ -10,18 +10,15 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.bytebuddy.asm.Advice; import org.apache.pekko.http.scaladsl.model.HttpHeader; @@ -62,58 +59,56 @@ public void methodAdvice(MethodTransformer transformer) { } @SuppressFBWarnings("BC_IMPOSSIBLE_INSTANCEOF") - @RequiresRequestContext(RequestContextSlot.IAST) static class RequestHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) static void onExit( - @Advice.This HttpRequest thiz, - @Advice.Return(readOnly = false) Seq headers, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This HttpRequest thiz, @Advice.Return(readOnly = false) Seq headers) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || headers == null || headers.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); - if (!propagation.isTainted(ctx, thiz)) { + if (!propagation.isTainted(to, thiz)) { return; } Iterator iterator = headers.iterator(); while (iterator.hasNext()) { HttpHeader h = iterator.next(); - if (propagation.isTainted(ctx, h)) { + if (propagation.isTainted(to, h)) { continue; } // unfortunately, the call to h.value() is instrumented, but // because the call to taint() only happens after, the call is a noop - propagation.taintObject(ctx, h, SourceTypes.REQUEST_HEADER_VALUE, h.name(), h.value()); + propagation.taintObject(to, h, SourceTypes.REQUEST_HEADER_VALUE, h.name(), h.value()); } } } - @RequiresRequestContext(RequestContextSlot.IAST) static class EntityAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation static void onExit( @Advice.This HttpRequest thiz, - @Advice.Return(readOnly = false, typing = DYNAMIC) Object entity, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false, typing = DYNAMIC) Object entity) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || entity == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { + return; + } - if (propagation.isTainted(ctx, entity)) { + if (propagation.isTainted(to, entity)) { return; } - propagation.taintObjectIfTainted(ctx, entity, thiz); + propagation.taintObjectIfTainted(to, entity, thiz); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/PathMatcherInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/PathMatcherInstrumentation.java index 299b3bed118..900434cbc65 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/PathMatcherInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/PathMatcherInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** @@ -46,12 +43,10 @@ public void methodAdvice(MethodTransformer transformer) { PathMatcherInstrumentation.class.getName() + "$PathMatcherAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class PathMatcherAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PATH_PARAMETER) - static void onExit( - @Advice.Argument(1) Object extractions, @ActiveRequestContext RequestContext reqCtx) { + static void onExit(@Advice.Argument(1) Object extractions) { if (!(extractions instanceof scala.Tuple1)) { return; } @@ -65,14 +60,14 @@ static void onExit( } final String stringValue = (String) value; - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); // in the test, 4 instances of PathMatcher$Match are created, all with the same value - if (module.isTainted(ctx, stringValue)) { + if (module.isTainted(to, stringValue)) { return; } - module.taintString(ctx, stringValue, SourceTypes.REQUEST_PATH_PARAMETER); + module.taintObject(to, stringValue, SourceTypes.REQUEST_PATH_PARAMETER); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/RequestContextInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/RequestContextInstrumentation.java index 25a3c5b44c5..71059e1adc7 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/RequestContextInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/RequestContextInstrumentation.java @@ -8,15 +8,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.bytebuddy.asm.Advice; import org.apache.pekko.http.scaladsl.model.HttpRequest; @@ -47,27 +45,27 @@ public void methodAdvice(MethodTransformer transformer) { } @SuppressFBWarnings("BC_IMPOSSIBLE_INSTANCEOF") - @RequiresRequestContext(RequestContextSlot.IAST) static class GetRequestAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation static void onExit( - @Advice.This RequestContext requestContext, - @Advice.Return HttpRequest request, - @ActiveRequestContext datadog.trace.api.gateway.RequestContext reqCtx) { + @Advice.This RequestContext requestContext, @Advice.Return HttpRequest request) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { + return; + } - if (propagation.isTainted(ctx, request)) { + if (propagation.isTainted(to, request)) { return; } - propagation.taintObjectIfTainted(ctx, request, requestContext); + propagation.taintObjectIfTainted(to, request, requestContext); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/UriInstrumentation.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/UriInstrumentation.java index 663daebf2f3..4b65f5e47ad 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/UriInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/UriInstrumentation.java @@ -9,18 +9,15 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.apache.pekko.http.scaladsl.model.Uri; import scala.Tuple2; @@ -67,40 +64,32 @@ public void methodAdvice(MethodTransformer transformer) { UriInstrumentation.class.getName() + "$TaintQueryAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) static class TaintQueryStringAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation - static void after( - @Advice.This Uri uri, - @Advice.Return scala.Option ret, - @ActiveRequestContext RequestContext reqCtx) { + static void after(@Advice.This Uri uri, @Advice.Return scala.Option ret) { PropagationModule mod = InstrumentationBridge.PROPAGATION; if (mod == null || ret.isEmpty()) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - mod.taintStringIfTainted(ctx, ret.get(), uri); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + mod.taintObjectIfTainted(to, ret.get(), uri); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintQueryAdvice { // bind uri to a variable of type Object so that this advice can also // be used from FromDataInstrumentaton @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - static void after( - @Advice.This /*Uri*/ Object uri, - @Advice.Return Uri.Query ret, - @ActiveRequestContext RequestContext reqCtx) { + static void after(@Advice.This /*Uri*/ Object uri, @Advice.Return Uri.Query ret) { PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || ret.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!prop.isTainted(ctx, uri)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!prop.isTainted(to, uri)) { return; } @@ -108,8 +97,8 @@ static void after( while (iterator.hasNext()) { Tuple2 pair = iterator.next(); final String name = pair._1(), value = pair._2(); - prop.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintCookieFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintCookieFunction.java index bc3e83b493b..d9fa7f7c2da 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintCookieFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintCookieFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import org.apache.pekko.http.scaladsl.model.headers.HttpCookiePair; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -21,14 +21,14 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null || httpCookiePair == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } final String name = httpCookiePair.name(); final String value = httpCookiePair.value(); - mod.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - mod.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + mod.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + mod.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); return v1; } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintFutureHelper.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintFutureHelper.java index fe1459d632f..4bed695c251 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintFutureHelper.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintFutureHelper.java @@ -2,7 +2,7 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.compat.java8.JFunction1; import scala.concurrent.ExecutionContext; import scala.concurrent.Future; @@ -12,9 +12,9 @@ public static Future wrapFuture( Future f, Object input, PropagationModule mod, ExecutionContext ec) { JFunction1 mapf = t -> { - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - mod.taintObjectIfTainted(ctx, t, input); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + mod.taintObjectIfTainted(to, t, input); } return t; }; diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMapFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMapFunction.java index aaf2b8ee79a..4a27ed4db61 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMapFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMapFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.Tuple2; import scala.collection.Iterator; @@ -24,16 +24,16 @@ public Tuple1> apply(Tuple1> v1) { return v1; } - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } Iterator> iterator = m.iterator(); while (iterator.hasNext()) { Tuple2 e = iterator.next(); final String name = e._1(), value = e._2(); - prop.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } return v1; diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMultiMapFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMultiMapFunction.java index 58dcebd688b..31990f9fc5e 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMultiMapFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintMultiMapFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Tuple1; import scala.Tuple2; import scala.collection.Iterator; @@ -25,18 +25,18 @@ public Tuple1>> apply(Tuple1>> return v1; } - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } Iterator>> entriesIterator = m.iterator(); while (entriesIterator.hasNext()) { Tuple2> e = entriesIterator.next(); final String name = e._1(); - mod.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + mod.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); List values = e._2(); for (final String value : ScalaToJava.listAsList(values)) { - mod.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintOptionalCookieFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintOptionalCookieFunction.java index a8b1569945c..a5ac1dc1753 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintOptionalCookieFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintOptionalCookieFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import org.apache.pekko.http.scaladsl.model.headers.HttpCookiePair; import scala.Option; import scala.Tuple1; @@ -22,15 +22,15 @@ public Tuple1> apply(Tuple1> v1) { if (mod == null || httpCookiePair.isEmpty()) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } final HttpCookiePair cookie = httpCookiePair.get(); final String name = cookie.name(); final String value = cookie.value(); - mod.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - mod.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + mod.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + mod.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); return v1; } } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintParametersFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintParametersFunction.java index 1ae24ca9b3c..5c4d2edfc03 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintParametersFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintParametersFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import scala.Function1; import scala.Option; import scala.Tuple1; @@ -34,8 +34,8 @@ public Tuple1 apply(Tuple1 v1) { value = option.get(); } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } @@ -44,11 +44,11 @@ public Tuple1 apply(Tuple1 v1) { while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof String) { - mod.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else if (value instanceof String) { - mod.taintString(ctx, (String) value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } return v1; diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestContextFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestContextFunction.java index 7e1d0dda2e7..7ffd089ba8e 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestContextFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestContextFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import org.apache.pekko.http.scaladsl.server.RequestContext; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -21,11 +21,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, reqCtx, SourceTypes.REQUEST_BODY); + mod.taintObject(to, reqCtx, SourceTypes.REQUEST_BODY); return v1; } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestFunction.java index 2c11c014ccd..0b6052ae135 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintRequestFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.pekko.http.scaladsl.model.HttpRequest; import scala.Tuple1; @@ -22,11 +22,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, httpRequest, SourceTypes.REQUEST_BODY); + mod.taintObject(to, httpRequest, SourceTypes.REQUEST_BODY); return v1; } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintSeqFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintSeqFunction.java index dc49d4f5efc..9cf0385916b 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintSeqFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintSeqFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Set; @@ -28,8 +28,8 @@ public Tuple1>> apply(Tuple1> iterator = seq.iterator(); @@ -39,9 +39,9 @@ public Tuple1>> apply(Tuple1 apply(Tuple1 v1) { value = option.get(); } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } @@ -51,11 +51,11 @@ public Tuple1 apply(Tuple1 v1) { while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof String) { - mod.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else if (value instanceof String) { - mod.taintString(ctx, (String) value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + mod.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } return v1; diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUnmarshaller.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUnmarshaller.java index 17fa5a8fa7c..40e5a9a2bc3 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUnmarshaller.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUnmarshaller.java @@ -3,7 +3,7 @@ import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.instrumentation.pekkohttp.iast.UnmarshallerInstrumentation; import org.apache.pekko.http.scaladsl.unmarshalling.Unmarshaller; import org.apache.pekko.stream.Materializer; @@ -30,9 +30,9 @@ public TaintUnmarshaller(PropagationModule propagationModule, Unmarshaller @Override public Future apply(A value, ExecutionContext ec, Materializer materializer) { - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - propagationModule.taintObject(ctx, value, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + propagationModule.taintObject(to, value, SourceTypes.REQUEST_BODY); } return delegate.apply(value, ec, materializer); } diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUriFunction.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUriFunction.java index 799602c9833..aad4468f799 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUriFunction.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/iast/helpers/TaintUriFunction.java @@ -4,7 +4,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import org.apache.pekko.http.scaladsl.model.Uri; import scala.Tuple1; import scala.compat.java8.JFunction1; @@ -20,11 +20,11 @@ public Tuple1 apply(Tuple1 v1) { if (mod == null) { return v1; } - IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { return v1; } - mod.taintObject(ctx, uri, SourceTypes.REQUEST_QUERY); + mod.taintObject(to, uri, SourceTypes.REQUEST_QUERY); return v1; } diff --git a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/CookieParamInjectorAdvice.java b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/CookieParamInjectorAdvice.java index 282c2ec34af..60d68b8c6e9 100644 --- a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/CookieParamInjectorAdvice.java +++ b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/CookieParamInjectorAdvice.java @@ -1,38 +1,32 @@ package datadog.trace.instrumentation.resteasy; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import net.bytebuddy.asm.Advice; -@RequiresRequestContext(RequestContextSlot.IAST) public class CookieParamInjectorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) public static void onExit( - @Advice.Return Object result, - @Advice.FieldValue("paramName") String paramName, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Object result, @Advice.FieldValue("paramName") String paramName) { if (result instanceof String || result instanceof Collection) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (result instanceof Collection) { Collection collection = (Collection) result; for (Object o : collection) { if (o instanceof String) { - module.taintString(ctx, (String) o, SourceTypes.REQUEST_COOKIE_VALUE, paramName); + module.taintObject(to, o, SourceTypes.REQUEST_COOKIE_VALUE, paramName); } } } else { - module.taintString(ctx, (String) result, SourceTypes.REQUEST_COOKIE_VALUE, paramName); + module.taintObject(to, result, SourceTypes.REQUEST_COOKIE_VALUE, paramName); } } } diff --git a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/FormParamInjectorAdvice.java b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/FormParamInjectorAdvice.java index 5068bd1b3f9..e62b192c767 100644 --- a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/FormParamInjectorAdvice.java +++ b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/FormParamInjectorAdvice.java @@ -1,38 +1,32 @@ package datadog.trace.instrumentation.resteasy; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import net.bytebuddy.asm.Advice; -@RequiresRequestContext(RequestContextSlot.IAST) public class FormParamInjectorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Return Object result, - @Advice.FieldValue("paramName") String paramName, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Object result, @Advice.FieldValue("paramName") String paramName) { if (result instanceof String || result instanceof Collection) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (result instanceof Collection) { Collection collection = (Collection) result; for (Object o : collection) { if (o instanceof String) { - module.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + module.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else { - module.taintString(ctx, (String) result, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + module.taintObject(to, result, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } diff --git a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/HeaderParamInjectorAdvice.java b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/HeaderParamInjectorAdvice.java index 1dc2e4afc07..4619c0b2845 100644 --- a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/HeaderParamInjectorAdvice.java +++ b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/HeaderParamInjectorAdvice.java @@ -1,38 +1,32 @@ package datadog.trace.instrumentation.resteasy; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import net.bytebuddy.asm.Advice; -@RequiresRequestContext(RequestContextSlot.IAST) public class HeaderParamInjectorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( - @Advice.Return Object result, - @Advice.FieldValue("paramName") String paramName, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Object result, @Advice.FieldValue("paramName") String paramName) { if (result instanceof String || result instanceof Collection) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (result instanceof Collection) { Collection collection = (Collection) result; for (Object o : collection) { if (o instanceof String) { - module.taintString(ctx, (String) o, SourceTypes.REQUEST_HEADER_VALUE, paramName); + module.taintObject(to, o, SourceTypes.REQUEST_HEADER_VALUE, paramName); } } } else { - module.taintString(ctx, (String) result, SourceTypes.REQUEST_HEADER_VALUE, paramName); + module.taintObject(to, result, SourceTypes.REQUEST_HEADER_VALUE, paramName); } } } diff --git a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/PathParamInjectorAdvice.java b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/PathParamInjectorAdvice.java index 0edfa333cf9..aaeacd72f7b 100644 --- a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/PathParamInjectorAdvice.java +++ b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/PathParamInjectorAdvice.java @@ -1,38 +1,32 @@ package datadog.trace.instrumentation.resteasy; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import net.bytebuddy.asm.Advice; -@RequiresRequestContext(RequestContextSlot.IAST) public class PathParamInjectorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Return Object result, - @Advice.FieldValue("paramName") String paramName, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Object result, @Advice.FieldValue("paramName") String paramName) { if (result instanceof String || result instanceof Collection) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (result instanceof Collection) { Collection collection = (Collection) result; for (Object o : collection) { if (o instanceof String) { - module.taintString(ctx, (String) o, SourceTypes.REQUEST_PATH_PARAMETER, paramName); + module.taintObject(to, o, SourceTypes.REQUEST_PATH_PARAMETER, paramName); } } } else { - module.taintString(ctx, (String) result, SourceTypes.REQUEST_PATH_PARAMETER, paramName); + module.taintObject(to, result, SourceTypes.REQUEST_PATH_PARAMETER, paramName); } } } diff --git a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/QueryParamInjectorAdvice.java b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/QueryParamInjectorAdvice.java index 3a3c7e323b0..e6a6dd2fc4a 100644 --- a/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/QueryParamInjectorAdvice.java +++ b/dd-java-agent/instrumentation/resteasy-appsec/src/main/java/datadog/trace/instrumentation/resteasy/QueryParamInjectorAdvice.java @@ -1,38 +1,32 @@ package datadog.trace.instrumentation.resteasy; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import net.bytebuddy.asm.Advice; -@RequiresRequestContext(RequestContextSlot.IAST) public class QueryParamInjectorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Return Object result, - @Advice.FieldValue("encodedName") String paramName, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Object result, @Advice.FieldValue("encodedName") String paramName) { if (result instanceof String || result instanceof Collection) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (result instanceof Collection) { Collection collection = (Collection) result; for (Object o : collection) { if (o instanceof String) { - module.taintString(ctx, (String) o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + module.taintObject(to, o, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } else { - module.taintString(ctx, (String) result, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); + module.taintObject(to, result, SourceTypes.REQUEST_PARAMETER_VALUE, paramName); } } } diff --git a/dd-java-agent/instrumentation/servlet-common/src/main/java/datadog/trace/instrumentation/servlet/HttpServletResponseInstrumentation.java b/dd-java-agent/instrumentation/servlet-common/src/main/java/datadog/trace/instrumentation/servlet/HttpServletResponseInstrumentation.java index 5140c386ade..f6af26bd47a 100644 --- a/dd-java-agent/instrumentation/servlet-common/src/main/java/datadog/trace/instrumentation/servlet/HttpServletResponseInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet-common/src/main/java/datadog/trace/instrumentation/servlet/HttpServletResponseInstrumentation.java @@ -12,6 +12,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Sink; @@ -19,6 +20,7 @@ import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.HttpResponseHeaderModule; import datadog.trace.api.iast.sink.UnvalidatedRedirectModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.util.Cookie; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -121,7 +123,8 @@ public static class EncodeURLAdvice { public static void onExit(@Advice.Argument(0) final String url, @Advice.Return String encoded) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (encoded != null && module != null) { - module.taintStringIfTainted(encoded, url); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, encoded, url); } } } diff --git a/dd-java-agent/instrumentation/servlet-common/src/test/groovy/HttpServletResponseInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet-common/src/test/groovy/HttpServletResponseInstrumentationTest.groovy index eb5d5dae0c8..bd5c3fe476b 100644 --- a/dd-java-agent/instrumentation/servlet-common/src/test/groovy/HttpServletResponseInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/servlet-common/src/test/groovy/HttpServletResponseInstrumentationTest.groovy @@ -182,7 +182,7 @@ class HttpServletResponseInstrumentationTest extends AgentTestRunner { then: noExceptionThrown() - 1 * module.taintStringIfTainted(_, "http://dummy.url.com") + 1 * module.taintObjectIfTainted(_, _, "http://dummy.url.com") 0 * _ } @@ -197,7 +197,7 @@ class HttpServletResponseInstrumentationTest extends AgentTestRunner { then: noExceptionThrown() - 1 * module.taintStringIfTainted(_, "http://dummy.url.com") + 1 * module.taintObjectIfTainted(_, _, "http://dummy.url.com") 0 * _ } diff --git a/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/MultipartInstrumentation.java b/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/MultipartInstrumentation.java index a27ffdc9329..90ee4a49ae2 100644 --- a/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/MultipartInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/MultipartInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import java.util.Collection; import net.bytebuddy.asm.Advice; @@ -64,93 +61,81 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$GetInputStreamAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetNameAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static String onExit( - @Advice.Return final String name, @ActiveRequestContext RequestContext reqCtx) { + public static String onExit(@Advice.Return final String name) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString( - ctx, name, SourceTypes.REQUEST_MULTIPART_PARAMETER, "Content-Disposition"); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject( + to, name, SourceTypes.REQUEST_MULTIPART_PARAMETER, "Content-Disposition"); } return name; } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) public static String onExit( - @Advice.Return final String value, - @Advice.Argument(0) final String name, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String value, @Advice.Argument(0) final String name) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, name); } return value; } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) public static void onExit( @Advice.Argument(0) final String headerName, - @Advice.Return Collection headerValues, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Collection headerValues) { if (null == headerValues || headerValues.isEmpty()) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final String value : headerValues) { - module.taintString(ctx, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, headerName); + module.taintObject(to, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, headerName); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final Collection headerNames, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Collection headerNames) { if (null == headerNames || headerNames.isEmpty()) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final String name : headerNames) { - module.taintString(ctx, name, SourceTypes.REQUEST_MULTIPART_PARAMETER); + module.taintObject(to, name, SourceTypes.REQUEST_MULTIPART_PARAMETER); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetInputStreamAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final InputStream inputStream, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final InputStream inputStream) { if (null == inputStream) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER); } } } diff --git a/dd-java-agent/instrumentation/servlet/request-3/src/test/groovy/MultipartInstrumentationForkedTest.groovy b/dd-java-agent/instrumentation/servlet/request-3/src/test/groovy/MultipartInstrumentationForkedTest.groovy index 9c2334e75fe..51679e1267c 100644 --- a/dd-java-agent/instrumentation/servlet/request-3/src/test/groovy/MultipartInstrumentationForkedTest.groovy +++ b/dd-java-agent/instrumentation/servlet/request-3/src/test/groovy/MultipartInstrumentationForkedTest.groovy @@ -3,6 +3,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockPart @@ -10,6 +11,7 @@ import foo.bar.smoketest.MockPart class MultipartInstrumentationForkedTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -18,7 +20,10 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -36,7 +41,7 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { runUnderIastTrace { part.getName() } then: - 1 * module.taintString(iastCtx, 'partName', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'Content-Disposition') + 1 * module.taintObject(to, 'partName', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'Content-Disposition') 0 * _ } @@ -50,7 +55,7 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { runUnderIastTrace { part.getHeader('headerName') } then: - 1 * module.taintString(iastCtx, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') + 1 * module.taintObject(to, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') 0 * _ } @@ -64,7 +69,7 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { runUnderIastTrace { part.getHeaders('headerName') } then: - 1 * module.taintString(iastCtx, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') + 1 * module.taintObject(to, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') 0 * _ } @@ -78,7 +83,7 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { runUnderIastTrace { part.getHeaderNames() } then: - 1 * module.taintString(iastCtx, 'headerName', SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, 'headerName', SourceTypes.REQUEST_MULTIPART_PARAMETER) 0 * _ } @@ -93,7 +98,7 @@ class MultipartInstrumentationForkedTest extends AgentTestRunner { runUnderIastTrace { part.getInputStream() } then: - 1 * module.taintObject(iastCtx, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER) 0 * _ } diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestCallSite.java b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestCallSite.java index b1dc62cb58a..d0683121197 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestCallSite.java +++ b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestCallSite.java @@ -7,7 +7,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import jakarta.servlet.http.HttpServletRequest; /** @@ -31,9 +31,9 @@ public static String afterPath( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - module.taintString(ctx, retValue, SourceTypes.REQUEST_PATH); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, retValue, SourceTypes.REQUEST_PATH); } } catch (final Throwable e) { module.onUnexpectedException("afterPath threw", e); @@ -53,9 +53,9 @@ public static StringBuffer afterGetRequestURL( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - module.taintObject(ctx, retValue, SourceTypes.REQUEST_URI); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, retValue, SourceTypes.REQUEST_URI); } } catch (final Throwable e) { module.onUnexpectedException("afterGetRequestURL threw", e); diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestInstrumentation.java b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestInstrumentation.java index f487a5ed35e..85896e00fed 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletRequestInstrumentation.java @@ -9,13 +9,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.iast.TaintableEnumeration; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Sink; @@ -24,6 +20,7 @@ import datadog.trace.api.iast.VulnerabilityTypes; import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.UnvalidatedRedirectModule; +import datadog.trace.api.iast.taint.TaintedObjects; import jakarta.servlet.http.Cookie; import java.util.Enumeration; import java.util.Map; @@ -98,14 +95,11 @@ public void methodAdvice(MethodTransformer transformer) { CLASS_NAME + "$GetRequestDispatcherAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String value, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String value) { if (value == null) { return; } @@ -113,19 +107,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( @Advice.Argument(0) final String name, - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -133,20 +125,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_HEADER_VALUE, name); + to, enumeration, module, SourceTypes.REQUEST_HEADER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_NAME) - public static void onExit( - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -154,21 +143,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = - TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_HEADER_NAME, true); + TaintableEnumeration.wrap(to, enumeration, module, SourceTypes.REQUEST_HEADER_NAME, true); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String value, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String value) { if (value == null) { return; } @@ -176,19 +161,16 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterValuesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String[] values, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String[] values) { if (values == null || values.length == 0) { return; } @@ -196,20 +178,17 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final String value : values) { - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterMapAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - public static void onExit( - @Advice.Return final Map parameters, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Map parameters) { if (parameters == null || parameters.isEmpty()) { return; } @@ -217,27 +196,24 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Map.Entry entry : parameters.entrySet()) { final String name = entry.getKey(); - module.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + module.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); final String[] values = entry.getValue(); if (values != null) { for (final String value : entry.getValue()) { - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_NAME) - public static void onExit( - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -245,20 +221,18 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_PARAMETER_NAME, true); + to, enumeration, module, SourceTypes.REQUEST_PARAMETER_NAME, true); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetCookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onExit( - @Advice.Return final Cookie[] cookies, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Cookie[] cookies) { if (cookies == null || cookies.length == 0) { return; } @@ -266,19 +240,17 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Cookie cookie : cookies) { - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetQueryStringAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_QUERY) - public static void onExit( - @Advice.Return final String queryString, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final String queryString) { if (queryString == null) { return; } @@ -286,17 +258,15 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, queryString, SourceTypes.REQUEST_QUERY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, queryString, SourceTypes.REQUEST_QUERY); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetBodyAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) - public static void onExit( - @Advice.Return final Object body, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Object body) { if (body == null) { return; } @@ -304,8 +274,8 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, body, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, body, SourceTypes.REQUEST_BODY); } } diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletResponseInstrumentation.java b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletResponseInstrumentation.java index 5c4d4052003..eab17bef7f7 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletResponseInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaHttpServletResponseInstrumentation.java @@ -12,6 +12,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.Sink; @@ -19,6 +20,7 @@ import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.HttpResponseHeaderModule; import datadog.trace.api.iast.sink.UnvalidatedRedirectModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.api.iast.util.Cookie; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -120,7 +122,8 @@ public static void onExit(@Advice.Argument(0) final String url, @Advice.Return S final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { if (null != url && !url.isEmpty() && null != encoded && !encoded.isEmpty()) { - module.taintStringIfTainted(encoded, url); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, encoded, url); } } } diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaMultipartInstrumentation.java b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaMultipartInstrumentation.java index 4d94db217d8..76d0719f2bf 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaMultipartInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/JakartaMultipartInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import java.util.Collection; import net.bytebuddy.asm.Advice; @@ -60,93 +57,91 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$GetInputStreamAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetNameAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static String onExit( - @Advice.Return final String name, @ActiveRequestContext RequestContext reqCtx) { + public static String onExit(@Advice.Return final String name) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString( - ctx, name, SourceTypes.REQUEST_MULTIPART_PARAMETER, "Content-Disposition"); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject( + to, name, SourceTypes.REQUEST_MULTIPART_PARAMETER, "Content-Disposition"); + } } return name; } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) public static String onExit( - @Advice.Return final String value, - @Advice.Argument(0) final String name, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String value, @Advice.Argument(0) final String name) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, name); + } } return value; } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) public static void onExit( @Advice.Argument(0) final String headerName, - @Advice.Return Collection headerValues, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return Collection headerValues) { if (null == headerValues || headerValues.isEmpty()) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - for (final String value : headerValues) { - module.taintString(ctx, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, headerName); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + for (final String value : headerValues) { + module.taintObject(to, value, SourceTypes.REQUEST_MULTIPART_PARAMETER, headerName); + } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final Collection headerNames, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Collection headerNames) { if (null == headerNames || headerNames.isEmpty()) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - for (final String name : headerNames) { - module.taintString(ctx, name, SourceTypes.REQUEST_MULTIPART_PARAMETER); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + for (final String name : headerNames) { + module.taintObject(to, name, SourceTypes.REQUEST_MULTIPART_PARAMETER); + } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetInputStreamAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_MULTIPART_PARAMETER) - public static void onExit( - @Advice.Return final InputStream inputStream, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final InputStream inputStream) { if (null == inputStream) { return; } final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER); + } } } } diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletRequestInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletRequestInstrumentationTest.groovy index a314b59ddf3..48b6fb7e238 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletRequestInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletRequestInstrumentationTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule import datadog.trace.api.iast.sink.ApplicationModule import datadog.trace.api.iast.sink.UnvalidatedRedirectModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.JakartaHttpServletRequestTestSuite @@ -24,6 +25,7 @@ import jakarta.servlet.http.HttpSession class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -31,7 +33,10 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void cleanup() { @@ -51,7 +56,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == 'value' 1 * mock.getHeader('header') >> 'value' - 1 * iastModule.taintString(iastCtx, 'value', SourceTypes.REQUEST_HEADER_VALUE, 'header') + 1 * iastModule.taintObject(to, 'value', SourceTypes.REQUEST_HEADER_VALUE, 'header') 0 * _ where: @@ -72,7 +77,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == headers 1 * mock.getHeaders('headers') >> Collections.enumeration(headers) - headers.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_VALUE, 'headers') } + headers.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_HEADER_VALUE, 'headers') } 0 * _ where: @@ -93,7 +98,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == headers 1 * mock.getHeaderNames() >> Collections.enumeration(headers) - headers.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_NAME, it) } + headers.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_HEADER_NAME, it) } 0 * _ where: @@ -113,7 +118,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == 'value' 1 * mock.getParameter('parameter') >> 'value' - 1 * iastModule.taintString(iastCtx, 'value', SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') + 1 * iastModule.taintObject(to, 'value', SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') 0 * _ where: @@ -134,7 +139,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == values 1 * mock.getParameterValues('parameter') >> { values as String[] } - values.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') } + values.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') } 0 * _ where: @@ -156,9 +161,9 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { result == parameters 1 * mock.getParameterMap() >> parameters parameters.each { key, values -> - 1 * iastModule.taintString(iastCtx, key, SourceTypes.REQUEST_PARAMETER_NAME, key) + 1 * iastModule.taintObject(to, key, SourceTypes.REQUEST_PARAMETER_NAME, key) values.each { value -> - 1 * iastModule.taintString(iastCtx, value, SourceTypes.REQUEST_PARAMETER_VALUE, key) + 1 * iastModule.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, key) } } 0 * _ @@ -182,7 +187,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == parameters 1 * mock.getParameterNames() >> Collections.enumeration(parameters) - parameters.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_PARAMETER_NAME, it) } + parameters.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_PARAMETER_NAME, it) } 0 * _ where: @@ -203,7 +208,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == cookies 1 * mock.getCookies() >> cookies - cookies.each { 1 * iastModule.taintObject(iastCtx, it, SourceTypes.REQUEST_COOKIE_VALUE) } + cookies.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_COOKIE_VALUE) } 0 * _ where: @@ -280,7 +285,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == queryString 1 * mock.getQueryString() >> queryString - 1 * iastModule.taintString(iastCtx, queryString, SourceTypes.REQUEST_QUERY) + 1 * iastModule.taintObject(to, queryString, SourceTypes.REQUEST_QUERY) 0 * _ where: @@ -301,7 +306,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == is 1 * mock.getInputStream() >> is - 1 * iastModule.taintObject(iastCtx, is, SourceTypes.REQUEST_BODY) + 1 * iastModule.taintObject(to, is, SourceTypes.REQUEST_BODY) 0 * _ where: @@ -322,7 +327,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == reader 1 * mock.getReader() >> reader - 1 * iastModule.taintObject(iastCtx, reader, SourceTypes.REQUEST_BODY) + 1 * iastModule.taintObject(to, reader, SourceTypes.REQUEST_BODY) 0 * _ where: @@ -365,7 +370,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == uri 1 * mock.getRequestURI() >> uri - 1 * iastModule.taintString(iastCtx, uri, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, uri, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -386,7 +391,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == pathInfo 1 * mock.getPathInfo() >> pathInfo - 1 * iastModule.taintString(iastCtx, pathInfo, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, pathInfo, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -407,7 +412,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == pathTranslated 1 * mock.getPathTranslated() >> pathTranslated - 1 * iastModule.taintString(iastCtx, pathTranslated, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, pathTranslated, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -428,7 +433,7 @@ class JakartaHttpServletRequestInstrumentationTest extends AgentTestRunner { then: result == url 1 * mock.getRequestURL() >> url - 1 * iastModule.taintObject(iastCtx, url, SourceTypes.REQUEST_URI) + 1 * iastModule.taintObject(to, url, SourceTypes.REQUEST_URI) 0 * _ where: diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletResponseInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletResponseInstrumentationTest.groovy index 025d42f97ac..c6c9c11d4ad 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletResponseInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaHttpServletResponseInstrumentationTest.groovy @@ -219,7 +219,7 @@ class JakartaHttpServletResponseInstrumentationTest extends AgentTestRunner { result = response.encodeRedirectURL(url) then: - 1 * module.taintStringIfTainted(_, url) >> { args -> expected = args[0] } + 1 * module.taintObjectIfTainted(_, _, url) >> { args -> expected = args[1] } 0 * _ result == expected } @@ -236,7 +236,7 @@ class JakartaHttpServletResponseInstrumentationTest extends AgentTestRunner { result = response.encodeURL(url) then: - 1 * module.taintStringIfTainted(_, url) >> { args -> expected = args[0] } + 1 * module.taintObjectIfTainted(_, _, url) >> { args -> expected = args[1] } 0 * _ expected == result } diff --git a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaMultipartInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaMultipartInstrumentationTest.groovy index c7f364919b3..9fc038ea301 100644 --- a/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaMultipartInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/JakartaMultipartInstrumentationTest.groovy @@ -3,6 +3,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.smoketest.MockPart @@ -10,6 +11,7 @@ import foo.bar.smoketest.MockPart class JakartaMultipartInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -17,7 +19,10 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @Override @@ -35,7 +40,7 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { runUnderIastTrace { part.getName() } then: - 1 * module.taintString(iastCtx, 'partName', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'Content-Disposition') + 1 * module.taintObject(to, 'partName', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'Content-Disposition') 0 * _ } @@ -49,7 +54,7 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { runUnderIastTrace { part.getHeader('headerName') } then: - 1 * module.taintString(iastCtx, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') + 1 * module.taintObject(to, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') 0 * _ } @@ -63,7 +68,7 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { runUnderIastTrace { part.getHeaders('headerName') } then: - 1 * module.taintString(iastCtx, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') + 1 * module.taintObject(to, 'headerValue', SourceTypes.REQUEST_MULTIPART_PARAMETER, 'headerName') 0 * _ } @@ -77,7 +82,7 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { runUnderIastTrace { part.getHeaderNames() } then: - 1 * module.taintString(iastCtx, 'headerName', SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, 'headerName', SourceTypes.REQUEST_MULTIPART_PARAMETER) 0 * _ } @@ -92,7 +97,7 @@ class JakartaMultipartInstrumentationTest extends AgentTestRunner { runUnderIastTrace { part.getInputStream() } then: - 1 * module.taintObject(iastCtx, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER) + 1 * module.taintObject(to, inputStream, SourceTypes.REQUEST_MULTIPART_PARAMETER) 0 * _ } diff --git a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/CookieInstrumentation.java b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/CookieInstrumentation.java index 5f2d997ccff..6461c8eb111 100644 --- a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/CookieInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/CookieInstrumentation.java @@ -5,18 +5,15 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -47,19 +44,16 @@ public void methodAdvice(final MethodTransformer transformer) { getClass().getName() + "$GetValueAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetNameAdvice { @Advice.OnMethodExit @Source(SourceTypes.REQUEST_COOKIE_NAME) public static void afterGetName( - @Advice.This final Object self, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Object self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); } catch (final Throwable e) { module.onUnexpectedException("afterGetName threw", e); } @@ -67,7 +61,6 @@ public static void afterGetName( } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetValueAdvice { @Advice.OnMethodExit @@ -75,13 +68,12 @@ public static class GetValueAdvice { public static void afterGetValue( @Advice.This final Object self, @Advice.FieldValue("name") final String name, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_COOKIE_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_COOKIE_VALUE, name); } catch (final Throwable e) { module.onUnexpectedException("getValue threw", e); } diff --git a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestCallSite.java b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestCallSite.java index 6eb24635b92..fb105b386fe 100644 --- a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestCallSite.java +++ b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestCallSite.java @@ -7,7 +7,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.api.iast.taint.TaintedObjects; import javax.servlet.http.HttpServletRequest; /** @@ -31,9 +31,9 @@ public static String afterPath( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - module.taintString(ctx, retValue, SourceTypes.REQUEST_PATH); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, retValue, SourceTypes.REQUEST_PATH); } } catch (final Throwable e) { module.onUnexpectedException("afterPath threw", e); @@ -53,9 +53,9 @@ public static StringBuffer afterGetRequestURL( final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { try { - final IastContext ctx = IastContext.Provider.get(AgentTracer.activeSpan()); - if (ctx != null) { - module.taintObject(ctx, retValue, SourceTypes.REQUEST_URI); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to != null) { + module.taintObject(to, retValue, SourceTypes.REQUEST_URI); } } catch (final Throwable e) { module.onUnexpectedException("afterGetRequestURL threw", e); diff --git a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestInstrumentation.java b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestInstrumentation.java index 5ae518435d5..6c486b3931b 100644 --- a/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/servlet/src/main/java/datadog/trace/instrumentation/servlet/http/HttpServletRequestInstrumentation.java @@ -9,13 +9,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.iast.TaintableEnumeration; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Sink; @@ -24,6 +20,7 @@ import datadog.trace.api.iast.VulnerabilityTypes; import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.UnvalidatedRedirectModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Enumeration; import java.util.Map; import javax.servlet.http.Cookie; @@ -98,14 +95,11 @@ public void methodAdvice(MethodTransformer transformer) { CLASS_NAME + "$GetRequestDispatcherAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String value, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String value) { if (value == null) { return; } @@ -113,19 +107,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( @Advice.Argument(0) final String name, - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -133,20 +125,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_HEADER_VALUE, name); + to, enumeration, module, SourceTypes.REQUEST_HEADER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetHeaderNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_NAME) - public static void onExit( - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -154,21 +143,17 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = - TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_HEADER_NAME, true); + TaintableEnumeration.wrap(to, enumeration, module, SourceTypes.REQUEST_HEADER_NAME, true); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String value, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String value) { if (value == null) { return; } @@ -176,19 +161,16 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterValuesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( - @Advice.Argument(0) final String name, - @Advice.Return final String[] values, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Argument(0) final String name, @Advice.Return final String[] values) { if (values == null || values.length == 0) { return; } @@ -196,20 +178,17 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final String value : values) { - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterMapAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - public static void onExit( - @Advice.Return final Map parameters, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Map parameters) { if (parameters == null || parameters.isEmpty()) { return; } @@ -217,27 +196,24 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Map.Entry entry : parameters.entrySet()) { final String name = entry.getKey(); - module.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + module.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); final String[] values = entry.getValue(); if (values != null) { for (final String value : entry.getValue()) { - module.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + module.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetParameterNamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_NAME) - public static void onExit( - @Advice.Return(readOnly = false) Enumeration enumeration, - @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return(readOnly = false) Enumeration enumeration) { if (enumeration == null) { return; } @@ -245,20 +221,18 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); enumeration = TaintableEnumeration.wrap( - ctx, enumeration, module, SourceTypes.REQUEST_PARAMETER_NAME, true); + to, enumeration, module, SourceTypes.REQUEST_PARAMETER_NAME, true); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetCookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onExit( - @Advice.Return final Cookie[] cookies, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Cookie[] cookies) { if (cookies == null || cookies.length == 0) { return; } @@ -266,19 +240,17 @@ public static void onExit( if (module == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Cookie cookie : cookies) { - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetQueryStringAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_QUERY) - public static void onExit( - @Advice.Return final String queryString, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final String queryString) { if (queryString == null) { return; } @@ -286,17 +258,15 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintString(ctx, queryString, SourceTypes.REQUEST_QUERY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, queryString, SourceTypes.REQUEST_QUERY); } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetBodyAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) - public static void onExit( - @Advice.Return final Object body, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Object body) { if (body == null) { return; } @@ -304,8 +274,8 @@ public static void onExit( if (module == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, body, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, body, SourceTypes.REQUEST_BODY); } } diff --git a/dd-java-agent/instrumentation/servlet/src/test/groovy/CookieInstrumentationTest.groovy b/dd-java-agent/instrumentation/servlet/src/test/groovy/CookieInstrumentationTest.groovy index 57f07aa3ff7..1c11c808153 100644 --- a/dd-java-agent/instrumentation/servlet/src/test/groovy/CookieInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/servlet/src/test/groovy/CookieInstrumentationTest.groovy @@ -3,6 +3,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic @@ -16,6 +17,7 @@ class CookieInstrumentationTest extends AgentTestRunner { private static final String VALUE = 'value' private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -24,7 +26,10 @@ class CookieInstrumentationTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'test getName'() { @@ -38,7 +43,7 @@ class CookieInstrumentationTest extends AgentTestRunner { then: result == NAME - 1 * iastModule.taintStringIfTainted(iastCtx, NAME, cookie, SourceTypes.REQUEST_COOKIE_NAME, NAME) + 1 * iastModule.taintObjectIfTainted(to, NAME, cookie, SourceTypes.REQUEST_COOKIE_NAME, NAME) } void 'test getValue'() { @@ -52,7 +57,7 @@ class CookieInstrumentationTest extends AgentTestRunner { then: result == VALUE - 1 * iastModule.taintStringIfTainted(iastCtx, VALUE, cookie, SourceTypes.REQUEST_COOKIE_VALUE, NAME) + 1 * iastModule.taintObjectIfTainted(to, VALUE, cookie, SourceTypes.REQUEST_COOKIE_VALUE, NAME) } protected E runUnderIastTrace(Closure cl) { diff --git a/dd-java-agent/instrumentation/servlet/src/test/groovy/HttpServletRequestTest.groovy b/dd-java-agent/instrumentation/servlet/src/test/groovy/HttpServletRequestTest.groovy index c025561b8b2..9662ca1f5a8 100644 --- a/dd-java-agent/instrumentation/servlet/src/test/groovy/HttpServletRequestTest.groovy +++ b/dd-java-agent/instrumentation/servlet/src/test/groovy/HttpServletRequestTest.groovy @@ -7,6 +7,7 @@ import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule import datadog.trace.api.iast.sink.UnvalidatedRedirectModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext @@ -21,6 +22,7 @@ import datadog.trace.agent.tooling.iast.TaintableEnumeration class HttpServletRequestTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -28,7 +30,10 @@ class HttpServletRequestTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } @@ -49,7 +54,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == 'value' 1 * mock.getHeader('header') >> 'value' - 1 * iastModule.taintString(iastCtx, 'value', SourceTypes.REQUEST_HEADER_VALUE, 'header') + 1 * iastModule.taintObject(to, 'value', SourceTypes.REQUEST_HEADER_VALUE, 'header') 0 * _ where: @@ -70,7 +75,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == headers 1 * mock.getHeaders('headers') >> Collections.enumeration(headers) - headers.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_VALUE, 'headers') } + headers.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_HEADER_VALUE, 'headers') } 0 * _ where: @@ -91,7 +96,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == headers 1 * mock.getHeaderNames() >> Collections.enumeration(headers) - headers.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_NAME, it) } + headers.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_HEADER_NAME, it) } 0 * _ where: @@ -111,7 +116,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == 'value' 1 * mock.getParameter('parameter') >> 'value' - 1 * iastModule.taintString(iastCtx, 'value', SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') + 1 * iastModule.taintObject(to, 'value', SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') 0 * _ where: @@ -132,7 +137,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == values 1 * mock.getParameterValues('parameter') >> { values as String[] } - values.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') } + values.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_PARAMETER_VALUE, 'parameter') } 0 * _ where: @@ -154,9 +159,9 @@ class HttpServletRequestTest extends AgentTestRunner { result == parameters 1 * mock.getParameterMap() >> parameters parameters.each { key, values -> - 1 * iastModule.taintString(iastCtx, key, SourceTypes.REQUEST_PARAMETER_NAME, key) + 1 * iastModule.taintObject(to, key, SourceTypes.REQUEST_PARAMETER_NAME, key) values.each { value -> - 1 * iastModule.taintString(iastCtx, value, SourceTypes.REQUEST_PARAMETER_VALUE, key) + 1 * iastModule.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, key) } } 0 * _ @@ -179,7 +184,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == parameters 1 * mock.getParameterNames() >> Collections.enumeration(parameters) - parameters.each { 1 * iastModule.taintString(iastCtx, it, SourceTypes.REQUEST_PARAMETER_NAME, it) } + parameters.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_PARAMETER_NAME, it) } 0 * _ where: @@ -200,7 +205,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == cookies 1 * mock.getCookies() >> cookies - cookies.each { 1 * iastModule.taintObject(iastCtx, it, SourceTypes.REQUEST_COOKIE_VALUE) } + cookies.each { 1 * iastModule.taintObject(to, it, SourceTypes.REQUEST_COOKIE_VALUE) } 0 * _ where: @@ -277,7 +282,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == queryString 1 * mock.getQueryString() >> queryString - 1 * iastModule.taintString(iastCtx, queryString, SourceTypes.REQUEST_QUERY) + 1 * iastModule.taintObject(to, queryString, SourceTypes.REQUEST_QUERY) 0 * _ where: @@ -298,7 +303,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == is 1 * mock.getInputStream() >> is - 1 * iastModule.taintObject(iastCtx, is, SourceTypes.REQUEST_BODY) + 1 * iastModule.taintObject(to, is, SourceTypes.REQUEST_BODY) 0 * _ where: @@ -319,7 +324,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == reader 1 * mock.getReader() >> reader - 1 * iastModule.taintObject(iastCtx, reader, SourceTypes.REQUEST_BODY) + 1 * iastModule.taintObject(to, reader, SourceTypes.REQUEST_BODY) 0 * _ where: @@ -362,7 +367,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == uri 1 * mock.getRequestURI() >> uri - 1 * iastModule.taintString(iastCtx, uri, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, uri, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -383,7 +388,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == pathInfo 1 * mock.getPathInfo() >> pathInfo - 1 * iastModule.taintString(iastCtx, pathInfo, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, pathInfo, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -404,7 +409,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == pathTranslated 1 * mock.getPathTranslated() >> pathTranslated - 1 * iastModule.taintString(iastCtx, pathTranslated, SourceTypes.REQUEST_PATH) + 1 * iastModule.taintObject(to, pathTranslated, SourceTypes.REQUEST_PATH) 0 * _ where: @@ -425,7 +430,7 @@ class HttpServletRequestTest extends AgentTestRunner { then: result == url 1 * mock.getRequestURL() >> url - 1 * iastModule.taintObject(iastCtx, url, SourceTypes.REQUEST_URI) + 1 * iastModule.taintObject(to, url, SourceTypes.REQUEST_URI) 0 * _ where: diff --git a/dd-java-agent/instrumentation/spring-core/src/main/java/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentation.java b/dd-java-agent/instrumentation/spring-core/src/main/java/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentation.java index da7a6f9a23d..3fd0fee5fc6 100644 --- a/dd-java-agent/instrumentation/spring-core/src/main/java/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-core/src/main/java/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentation.java @@ -8,9 +8,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -50,7 +52,8 @@ public static void checkReturnedObject( @Advice.Return String string, @Advice.Argument(0) final InputStream in) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (string != null && module != null) { - module.taintStringIfTainted(string, in); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, string, in); } } diff --git a/dd-java-agent/instrumentation/spring-core/src/test/groovy/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentationTest.groovy b/dd-java-agent/instrumentation/spring-core/src/test/groovy/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentationTest.groovy index 3447c8efdc6..f459e5862ff 100644 --- a/dd-java-agent/instrumentation/spring-core/src/test/groovy/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/spring-core/src/test/groovy/datadog/trace/instrumentation/springcore/StreamUtilsInstrumentationTest.groovy @@ -24,7 +24,7 @@ class StreamUtilsInstrumentationTest extends AgentTestRunner { StreamUtils.copyToString(new ByteArrayInputStream("test".getBytes()), StandardCharsets.ISO_8859_1) then: - 1 * module.taintStringIfTainted(_ as String, _ as InputStream) + 1 * module.taintObjectIfTainted(_, _ as String, _ as InputStream) 0 * _ } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/AbstractServerHttpRequestInstrumentation.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/AbstractServerHttpRequestInstrumentation.java index 80e63208d02..b684b401159 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/AbstractServerHttpRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/AbstractServerHttpRequestInstrumentation.java @@ -6,17 +6,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -39,18 +36,16 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$TaintHeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void after( - @Advice.Return Object object, @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return Object object) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintObject(ctx, object, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObject(to, object, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/DataBufferAsInputStreamAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/DataBufferAsInputStreamAdvice.java index cded50fb8e1..401cdf02dec 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/DataBufferAsInputStreamAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/DataBufferAsInputStreamAdvice.java @@ -1,8 +1,10 @@ package datadog.trace.instrumentation.springwebflux.server.iast; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.io.InputStream; import net.bytebuddy.asm.Advice; import org.springframework.core.io.buffer.DataBuffer; @@ -17,7 +19,7 @@ public static void after(@Advice.This DataBuffer dataBuffer, @Advice.Return Inpu if (mod == null || is == null) { return; } - - mod.taintObjectIfTainted(is, dataBuffer); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + mod.taintObjectIfTainted(to, is, dataBuffer); } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HandleMatchAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HandleMatchAdvice.java index c3f1f992e91..a43196d397f 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HandleMatchAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HandleMatchAdvice.java @@ -1,27 +1,22 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Map; import net.bytebuddy.asm.Advice; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.server.ServerWebExchange; -@RequiresRequestContext(RequestContextSlot.IAST) public class HandleMatchAdvice { @SuppressWarnings("Duplicates") @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PATH_PARAMETER) - public static void after( - @Advice.Argument(2) ServerWebExchange xchg, @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Argument(2) ServerWebExchange xchg) { Object templateVars = xchg.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); Object matrixVars = xchg.getAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE); @@ -29,7 +24,7 @@ public static void after( return; } - IastContext iastRequestContext = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { @@ -40,8 +35,7 @@ public static void after( if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } @@ -57,17 +51,12 @@ public static void after( for (Map.Entry> ie : value.entrySet()) { String innerKey = ie.getKey(); if (innerKey != null) { - module.taintString( - iastRequestContext, - innerKey, - SourceTypes.REQUEST_MATRIX_PARAMETER, - parameterName); + module.taintObject(to, innerKey, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } Iterable innerValues = ie.getValue(); if (innerValues != null) { for (String iv : innerValues) { - module.taintString( - iastRequestContext, iv, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); + module.taintObject(to, iv, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HttpMessageInstrumentation.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HttpMessageInstrumentation.java index 6d800b29445..79c0b63e4e9 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HttpMessageInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/HttpMessageInstrumentation.java @@ -7,17 +7,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -47,18 +44,16 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$TaintHeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void after( - @Advice.Return Object object, @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return Object object) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintObject(ctx, object, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObject(to, object, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/Jackson2TokenizerApplyAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/Jackson2TokenizerApplyAdvice.java index dac16ca00db..21f512254fe 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/Jackson2TokenizerApplyAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/Jackson2TokenizerApplyAdvice.java @@ -1,35 +1,30 @@ package datadog.trace.instrumentation.springwebflux.server.iast; import com.fasterxml.jackson.databind.util.TokenBuffer; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.springframework.core.io.buffer.DataBuffer; import reactor.core.publisher.Flux; -@RequiresRequestContext(RequestContextSlot.IAST) class Jackson2TokenizerApplyAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) public static void after( @Advice.Argument(0) DataBuffer dataBuffer, - @Advice.Return(readOnly = false) Flux flux, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return(readOnly = false) Flux flux) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || flux == null || dataBuffer == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (!propagation.isTainted(ctx, dataBuffer)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (!propagation.isTainted(to, dataBuffer)) { return; } - flux = flux.map(new TaintFluxElementsFunction<>(ctx, propagation)); + flux = flux.map(new TaintFluxElementsFunction<>(to, propagation)); } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ReactorServerHttpRequestInstrumentation.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ReactorServerHttpRequestInstrumentation.java index 4d4a73a8a72..fe90ce5ec6f 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ReactorServerHttpRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ReactorServerHttpRequestInstrumentation.java @@ -6,16 +6,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -38,17 +35,15 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$TaintHeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - public static void after( - @Advice.Return Object object, @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return Object object) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintObject(ctx, object, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObject(to, object, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/RequestHeaderMapResolveAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/RequestHeaderMapResolveAdvice.java index 75bec42145e..785e5a949b0 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/RequestHeaderMapResolveAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/RequestHeaderMapResolveAdvice.java @@ -1,48 +1,42 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; import net.bytebuddy.implementation.bytecode.assign.Assigner; import org.springframework.util.MultiValueMap; -@RequiresRequestContext(RequestContextSlot.IAST) public class RequestHeaderMapResolveAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void after( - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Map values, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return(typing = Assigner.Typing.DYNAMIC) Map values) { PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || values == null || values.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); if (values instanceof MultiValueMap) { for (Map.Entry> e : ((MultiValueMap) values).entrySet()) { final String name = e.getKey(); - prop.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); + prop.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); for (String v : e.getValue()) { - prop.taintString(ctx, v, SourceTypes.REQUEST_HEADER_VALUE, name); + prop.taintObject(to, v, SourceTypes.REQUEST_HEADER_VALUE, name); } } } else { for (Map.Entry e : ((Map) values).entrySet()) { final String name = e.getKey(); final String value = e.getValue(); - prop.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); - prop.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + prop.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); + prop.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ServerServletHttpRequestInstrumentation.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ServerServletHttpRequestInstrumentation.java index 0755022ab42..2db4b4f87de 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ServerServletHttpRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/ServerServletHttpRequestInstrumentation.java @@ -6,16 +6,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) @@ -38,17 +35,15 @@ public void methodAdvice(MethodTransformer transformer) { getClass().getName() + "$TaintHeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class TaintHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - public static void after( - @Advice.Return Object object, @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return Object object) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintObject(ctx, object, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObject(to, object, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintCookiesAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintCookiesAdvice.java index 291abe554d1..5a141f2b4dd 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintCookiesAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintCookiesAdvice.java @@ -1,37 +1,31 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import net.bytebuddy.asm.Advice; import org.springframework.http.HttpCookie; import org.springframework.util.MultiValueMap; -@RequiresRequestContext(RequestContextSlot.IAST) class TaintCookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - public static void after( - @Advice.Return MultiValueMap cookies, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return MultiValueMap cookies) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module == null || cookies.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (List cookieList : cookies.values()) { for (HttpCookie cookie : cookieList) { final String name = cookie.getName(); final String value = cookie.getValue(); - module.taintString(ctx, name, SourceTypes.REQUEST_COOKIE_NAME, name); - module.taintString(ctx, value, SourceTypes.REQUEST_COOKIE_VALUE, name); + module.taintObject(to, name, SourceTypes.REQUEST_COOKIE_NAME, name); + module.taintObject(to, value, SourceTypes.REQUEST_COOKIE_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintFluxElementsFunction.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintFluxElementsFunction.java index 6086d084f34..31ded86183a 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintFluxElementsFunction.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintFluxElementsFunction.java @@ -1,23 +1,23 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.function.Function; public class TaintFluxElementsFunction implements Function { - final IastContext ctx; + final TaintedObjects to; final PropagationModule propagation; - public TaintFluxElementsFunction(IastContext ctx, PropagationModule propagationModule) { - this.ctx = ctx; + public TaintFluxElementsFunction(TaintedObjects to, PropagationModule propagationModule) { + this.to = to; this.propagation = propagationModule; } @Override public T apply(T t) { - propagation.taintObject(ctx, t, SourceTypes.REQUEST_BODY); + propagation.taintObject(to, t, SourceTypes.REQUEST_BODY); return t; } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintGetBodyAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintGetBodyAdvice.java index ec2eaeaa155..dbcbc49b3ec 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintGetBodyAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintGetBodyAdvice.java @@ -1,33 +1,27 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.ReactiveHttpInputMessage; import reactor.core.publisher.Flux; /** @see ReactiveHttpInputMessage#getBody() */ -@RequiresRequestContext(RequestContextSlot.IAST) class TaintGetBodyAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - public static void after( - @Advice.Return(readOnly = false) Flux flux, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return(readOnly = false) Flux flux) { PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation == null || flux == null) { return; } // taint both the flux and the individual DataBuffers - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintObject(ctx, flux, SourceTypes.REQUEST_BODY); - flux = flux.map(new TaintFluxElementsFunction<>(ctx, propagation)); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObject(to, flux, SourceTypes.REQUEST_BODY); + flux = flux.map(new TaintFluxElementsFunction<>(to, propagation)); } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetAdvice.java index 58305275194..f04d8685bfc 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetAdvice.java @@ -1,28 +1,23 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Locale; import net.bytebuddy.asm.Advice; /** @see org.springframework.http.HttpHeaders#get(Object) */ -@RequiresRequestContext(RequestContextSlot.IAST) class TaintHttpHeadersGetAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void after( @Advice.This Object self, @Advice.Argument(0) Object arg, - @Advice.Return List values, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return List values) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module == null || values == null || values.isEmpty()) { @@ -31,10 +26,10 @@ public static void after( if (!(arg instanceof String)) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); String lc = ((String) arg).toLowerCase(Locale.ROOT); for (String value : values) { - module.taintStringIfTainted(ctx, value, self, SourceTypes.REQUEST_HEADER_VALUE, lc); + module.taintObjectIfTainted(to, value, self, SourceTypes.REQUEST_HEADER_VALUE, lc); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetFirstAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetFirstAdvice.java index 9a882277008..f4620d8ced3 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetFirstAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersGetFirstAdvice.java @@ -1,32 +1,25 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** @see org.springframework.http.HttpHeaders#getFirst(String) */ -@RequiresRequestContext(RequestContextSlot.IAST) class TaintHttpHeadersGetFirstAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void after( - @Advice.This Object self, - @Advice.Argument(0) String arg, - @Advice.Return String value, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This Object self, @Advice.Argument(0) String arg, @Advice.Return String value) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module == null || arg == null || value == null) { return; } - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, value, self, SourceTypes.REQUEST_HEADER_VALUE, arg); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, value, self, SourceTypes.REQUEST_HEADER_VALUE, arg); } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersToSingleValueMapAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersToSingleValueMapAdvice.java index 5a64eb49ff9..7a1ca88ff99 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersToSingleValueMapAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintHttpHeadersToSingleValueMapAdvice.java @@ -1,38 +1,31 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Map; import net.bytebuddy.asm.Advice; import org.springframework.http.HttpHeaders; /** @see HttpHeaders#toSingleValueMap() */ -@RequiresRequestContext(RequestContextSlot.IAST) class TaintHttpHeadersToSingleValueMapAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void after( - @Advice.This Object self, - @Advice.Return Map values, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.This Object self, @Advice.Return Map values) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module == null || values == null || values.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (Map.Entry e : values.entrySet()) { final String name = e.getKey(); final String value = e.getValue(); - module.taintStringIfTainted(ctx, name, self, SourceTypes.REQUEST_HEADER_NAME, name); - module.taintStringIfTainted(ctx, value, self, SourceTypes.REQUEST_HEADER_VALUE, name); + module.taintObjectIfTainted(to, name, self, SourceTypes.REQUEST_HEADER_NAME, name); + module.taintObjectIfTainted(to, value, self, SourceTypes.REQUEST_HEADER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintQueryParamsAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintQueryParamsAdvice.java index 31e0f23397a..40c361da191 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintQueryParamsAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintQueryParamsAdvice.java @@ -1,39 +1,33 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; import org.springframework.util.MultiValueMap; -@RequiresRequestContext(RequestContextSlot.IAST) class TaintQueryParamsAdvice { @SuppressWarnings("Duplicates") @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) - public static void after( - @Advice.Return MultiValueMap queryParams, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Return MultiValueMap queryParams) { final PropagationModule prop = InstrumentationBridge.PROPAGATION; if (prop == null || queryParams == null || queryParams.isEmpty()) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (Map.Entry> e : queryParams.entrySet()) { String name = e.getKey(); - prop.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + prop.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); for (String value : e.getValue()) { - prop.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + prop.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintReadOnlyHttpHeadersAdvice.java b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintReadOnlyHttpHeadersAdvice.java index 2efe52c6c79..d142bed4e4d 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintReadOnlyHttpHeadersAdvice.java +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/main/java/datadog/trace/instrumentation/springwebflux/server/iast/TaintReadOnlyHttpHeadersAdvice.java @@ -1,31 +1,24 @@ package datadog.trace.instrumentation.springwebflux.server.iast; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** @see org.springframework.http.HttpHeaders#get(Object) */ -@RequiresRequestContext(RequestContextSlot.IAST) class TaintReadOnlyHttpHeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void after( - @Advice.Argument(0) Object headers, - @Advice.Return Object retValue, - @ActiveRequestContext RequestContext reqCtx) { + public static void after(@Advice.Argument(0) Object headers, @Advice.Return Object retValue) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module == null || retValue == null) { return; } - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObjectIfTainted(ctx, retValue, headers); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, retValue, headers); } } diff --git a/dd-java-agent/instrumentation/spring-webflux-5/src/test/groovy/dd/trace/instrumentation/springwebflux/client/HeadersAdviceForkedTest.groovy b/dd-java-agent/instrumentation/spring-webflux-5/src/test/groovy/dd/trace/instrumentation/springwebflux/client/HeadersAdviceForkedTest.groovy index 7231985efb6..895149f746a 100644 --- a/dd-java-agent/instrumentation/spring-webflux-5/src/test/groovy/dd/trace/instrumentation/springwebflux/client/HeadersAdviceForkedTest.groovy +++ b/dd-java-agent/instrumentation/spring-webflux-5/src/test/groovy/dd/trace/instrumentation/springwebflux/client/HeadersAdviceForkedTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import foo.bar.DummyRequest @@ -13,6 +14,7 @@ import org.springframework.http.server.ServletServerHttpRequest class HeadersAdviceForkedTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -21,7 +23,10 @@ class HeadersAdviceForkedTest extends AgentTestRunner { @Override void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'Headers instrumentation'() { @@ -35,7 +40,7 @@ class HeadersAdviceForkedTest extends AgentTestRunner { runUnderIastTrace { request.getHeaders() } then: - 2 * module.taintObject(iastCtx , _ as Object, SourceTypes.REQUEST_HEADER_VALUE) + 2 * module.taintObject(to , _ as Object, SourceTypes.REQUEST_HEADER_VALUE) 0 * _ } diff --git a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateAndMatrixVariablesInstrumentation.java b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateAndMatrixVariablesInstrumentation.java index f82ef331165..60b02fc5a20 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateAndMatrixVariablesInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateAndMatrixVariablesInstrumentation.java @@ -23,6 +23,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.util.HashMap; @@ -189,6 +190,7 @@ public static void after( if (iastRequestContext != null) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { + final TaintedObjects to = iastRequestContext.getTaintedObjects(); if (templateVars instanceof Map) { for (Map.Entry e : ((Map) templateVars).entrySet()) { String parameterName = e.getKey(); @@ -196,8 +198,7 @@ public static void after( if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } @@ -213,20 +214,14 @@ public static void after( for (Map.Entry> ie : value.entrySet()) { String innerKey = ie.getKey(); if (innerKey != null) { - module.taintString( - iastRequestContext, - innerKey, - SourceTypes.REQUEST_MATRIX_PARAMETER, - parameterName); + module.taintObject( + to, innerKey, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } Iterable innerValues = ie.getValue(); if (innerValues != null) { for (String iv : innerValues) { - module.taintString( - iastRequestContext, - iv, - SourceTypes.REQUEST_MATRIX_PARAMETER, - parameterName); + module.taintObject( + to, iv, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateVariablesUrlHandlerInstrumentation.java b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateVariablesUrlHandlerInstrumentation.java index 41c4c77a798..524ba512001 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateVariablesUrlHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/main/java/datadog/trace/instrumentation/springweb/TemplateVariablesUrlHandlerInstrumentation.java @@ -23,6 +23,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.util.Map; @@ -148,14 +149,14 @@ public static void after( if (iastRequestContext != null) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { + final TaintedObjects to = iastRequestContext.getTaintedObjects(); for (Map.Entry e : map.entrySet()) { String parameterName = e.getKey(); String value = e.getValue(); if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/boot/SpringBootBasedTest.groovy b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/boot/SpringBootBasedTest.groovy index 694f5a660a9..f08833de4d2 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/boot/SpringBootBasedTest.groovy +++ b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/boot/SpringBootBasedTest.groovy @@ -5,10 +5,10 @@ import datadog.trace.agent.test.base.HttpServer import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDTags -import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.core.DDSpan import datadog.trace.instrumentation.springweb.SpringWebHttpServerDecorator @@ -259,7 +259,7 @@ class SpringBootBasedTest extends HttpServerTest TEST_WRITER.waitForTraces(1) then: - 1 * mod.taintString(_ as IastContext, '123', SourceTypes.REQUEST_PATH_PARAMETER, 'id') + 1 * mod.taintObject(_ as TaintedObjects, '123', SourceTypes.REQUEST_PATH_PARAMETER, 'id') 0 * mod._ cleanup: @@ -295,11 +295,11 @@ class SpringBootBasedTest extends HttpServerTest TEST_WRITER.waitForTraces(1) then: - 1 * mod.taintString(_ as IastContext, 'a=x,y;a=z', SourceTypes.REQUEST_PATH_PARAMETER, 'var') - 1 * mod.taintString(_ as IastContext, 'a', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - 1 * mod.taintString(_ as IastContext, 'x', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - 1 * mod.taintString(_ as IastContext, 'y', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - 1 * mod.taintString(_ as IastContext, 'z', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + 1 * mod.taintObject(_ as TaintedObjects, 'a=x,y;a=z', SourceTypes.REQUEST_PATH_PARAMETER, 'var') + 1 * mod.taintObject(_ as TaintedObjects, 'a', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + 1 * mod.taintObject(_ as TaintedObjects, 'x', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + 1 * mod.taintObject(_ as TaintedObjects, 'y', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + 1 * mod.taintObject(_ as TaintedObjects, 'z', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') 0 * mod._ cleanup: diff --git a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/urlhandlermapping/UrlHandlerMappingTest.groovy b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/urlhandlermapping/UrlHandlerMappingTest.groovy index f1d606f737f..c094c9bebee 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/urlhandlermapping/UrlHandlerMappingTest.groovy +++ b/dd-java-agent/instrumentation/spring-webmvc-3.1/src/test/groovy/test/urlhandlermapping/UrlHandlerMappingTest.groovy @@ -4,10 +4,10 @@ import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServer import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.api.DDSpanTypes -import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.core.DDSpan import datadog.trace.instrumentation.springweb.SpringWebHttpServerDecorator @@ -203,7 +203,7 @@ class UrlHandlerMappingTest extends HttpServerTest e : ((Map) templateVars).entrySet()) { String parameterName = e.getKey(); @@ -124,8 +126,7 @@ public static void after( if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } @@ -141,20 +142,13 @@ public static void after( for (Map.Entry> ie : value.entrySet()) { String innerKey = ie.getKey(); if (innerKey != null) { - module.taintString( - iastRequestContext, - innerKey, - SourceTypes.REQUEST_MATRIX_PARAMETER, - parameterName); + module.taintObject( + to, innerKey, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } Iterable innerValues = ie.getValue(); if (innerValues != null) { for (String iv : innerValues) { - module.taintString( - iastRequestContext, - iv, - SourceTypes.REQUEST_MATRIX_PARAMETER, - parameterName); + module.taintObject(to, iv, SourceTypes.REQUEST_MATRIX_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/main/java17/datadog/trace/instrumentation/springweb6/InterceptorPreHandleAdvice.java b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/main/java17/datadog/trace/instrumentation/springweb6/InterceptorPreHandleAdvice.java index cb5e563b748..3af4bf1a010 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/main/java17/datadog/trace/instrumentation/springweb6/InterceptorPreHandleAdvice.java +++ b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/main/java17/datadog/trace/instrumentation/springweb6/InterceptorPreHandleAdvice.java @@ -13,6 +13,7 @@ import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import jakarta.servlet.http.HttpServletRequest; @@ -85,14 +86,14 @@ public static void after( if (iastRequestContext != null) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { + final TaintedObjects to = iastRequestContext.getTaintedObjects(); for (Map.Entry e : map.entrySet()) { String parameterName = e.getKey(); String value = e.getValue(); if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/SpringBootBasedTest.groovy b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/SpringBootBasedTest.groovy index d3b2c80236b..d688728279e 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/SpringBootBasedTest.groovy +++ b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/boot/SpringBootBasedTest.groovy @@ -1,25 +1,15 @@ package datadog.trace.instrumentation.springweb6.boot -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.LOGIN -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.MATRIX_PARAM -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_HERE -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SECURE_SUCCESS -import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS - import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServer import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.api.ConfigDefaults import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDTags -import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.core.DDSpan import datadog.trace.instrumentation.springweb6.SetupSpecHelper @@ -37,6 +27,16 @@ import org.springframework.context.ConfigurableApplicationContext import org.springframework.web.servlet.HandlerInterceptor import spock.lang.Shared +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.LOGIN +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.MATRIX_PARAM +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_HERE +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SECURE_SUCCESS +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS + class SpringBootBasedTest extends HttpServerTest { @Override @@ -318,7 +318,7 @@ class SpringBootBasedTest extends HttpServerTest then: // spring-security filter causes uri matching to happen twice - (1.._) * mod.taintString(_ as IastContext, '123', SourceTypes.REQUEST_PATH_PARAMETER, 'id') + (1.._) * mod.taintObject(_ as TaintedObjects, '123', SourceTypes.REQUEST_PATH_PARAMETER, 'id') 0 * mod._ cleanup: @@ -357,11 +357,11 @@ class SpringBootBasedTest extends HttpServerTest then: // spring-security filter (AuthorizationFilter.java:95) causes uri matching to happen twice (or three times in recent spring (6.1+) versions) - (1.._) * mod.taintString(_ as IastContext, 'a=x,y', SourceTypes.REQUEST_PATH_PARAMETER, 'var') // this version of spring removes ;a=z - (1.._) * mod.taintString(_ as IastContext, 'a', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - (1.._) * mod.taintString(_ as IastContext, 'x', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - (1.._) * mod.taintString(_ as IastContext, 'y', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') - (1.._) * mod.taintString(_ as IastContext, 'z', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + (1.._) * mod.taintObject(_ as TaintedObjects, 'a=x,y', SourceTypes.REQUEST_PATH_PARAMETER, 'var') // this version of spring removes ;a=z + (1.._) * mod.taintObject(_ as TaintedObjects, 'a', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + (1.._) * mod.taintObject(_ as TaintedObjects, 'x', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + (1.._) * mod.taintObject(_ as TaintedObjects, 'y', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') + (1.._) * mod.taintObject(_ as TaintedObjects, 'z', SourceTypes.REQUEST_MATRIX_PARAMETER, 'var') 0 * mod._ cleanup: diff --git a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/urlhandlermapping/UrlHandlerMappingTest.groovy b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/urlhandlermapping/UrlHandlerMappingTest.groovy index 19fde0ed138..92fa8b81326 100644 --- a/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/urlhandlermapping/UrlHandlerMappingTest.groovy +++ b/dd-java-agent/instrumentation/spring-webmvc-6.0/src/test/groovy/datadog/trace/instrumentation/springweb6/urlhandlermapping/UrlHandlerMappingTest.groovy @@ -215,7 +215,7 @@ class UrlHandlerMappingTest extends HttpServerTest attributesFilter(); - @RequiresRequestContext(RequestContextSlot.IAST) public static class ParamsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @@ -70,20 +66,18 @@ public static void onEnter( @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( @Advice.Local("beforeParams") final Object beforeParams, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeParams != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class AttributesAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @@ -97,30 +91,27 @@ public static void onEnter( @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( @Advice.Local("beforeAttributes") final Object beforeAttributes, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeAttributes != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class DataAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) - public static void onExit( - @Advice.Argument(0) final Object data, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Argument(0) final Object data) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, data, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, data, SourceTypes.REQUEST_BODY); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/BufferInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/BufferInstrumentation.java index 1d757db9a54..e03ad8e5ff6 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/BufferInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/BufferInstrumentation.java @@ -11,17 +11,18 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** Propagation is way easier in io.vertx.core.buffer.impl.BufferImpl than in io.netty.Buffer */ @AutoService(InstrumenterModule.class) public class BufferInstrumentation extends InstrumenterModule.Iast - implements Instrumenter.ForSingleType, Instrumenter.HasTypeAdvice { + implements Instrumenter.ForSingleType { private final String className = BufferInstrumentation.class.getName(); @@ -39,11 +40,6 @@ public String instrumentedType() { return "io.vertx.core.buffer.impl.BufferImpl"; } - @Override - public void typeAdvice(TypeTransformer transformer) { - transformer.applyAdvice(new TaintableVisitor(instrumentedType())); - } - @Override public void methodAdvice(final MethodTransformer transformer) { transformer.applyAdvice( @@ -65,7 +61,8 @@ public static class ToStringAdvice { public static void get(@Advice.This final Object self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (result != null && module != null) { - module.taintStringIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self); } } } @@ -76,7 +73,8 @@ public static class GetByteBuffAdvice { public static void get(@Advice.This final Object self, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (result != null && module != null) { - module.taintObjectIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self); } } } @@ -88,7 +86,8 @@ public static void get( @Advice.Argument(0) final Object buffer, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (result != null && module != null) { - module.taintObjectIfTainted(result, buffer); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, buffer); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/CaseInsensitiveHeadersInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/CaseInsensitiveHeadersInstrumentation.java index 814985fcec0..324dd3f2d9b 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/CaseInsensitiveHeadersInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/CaseInsensitiveHeadersInstrumentation.java @@ -10,19 +10,16 @@ import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -79,85 +76,76 @@ public void methodAdvice(MethodTransformer transformer) { className + "$NamesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void afterGet( @Advice.This final Object self, @Advice.Argument(0) final String name, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintStringIfTainted( - ctx, result, self, SourceTypes.REQUEST_PARAMETER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted( + to, result, self, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAllAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void afterGetAll( @Advice.This final Object self, @Advice.Argument(0) final String name, - @Advice.Return final Collection result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Collection result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { for (final String value : result) { - propagation.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + propagation.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class EntriesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void afterEntries( @Advice.This final Object self, - @Advice.Return final List> result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final List> result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { final Set names = new HashSet<>(); for (final Map.Entry entry : result) { final String name = entry.getKey(); final String value = entry.getValue(); if (names.add(name)) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); } - propagation.taintString(ctx, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); + propagation.taintObject(to, value, SourceTypes.REQUEST_PARAMETER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class NamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_PARAMETER_NAME) public static void afterNames( - @Advice.This final Object self, - @Advice.Return final Set result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Object self, @Advice.Return final Set result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { for (final String name : result) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_PARAMETER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_PARAMETER_NAME, name); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HeadersAdaptorInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HeadersAdaptorInstrumentation.java index 7ede6c65d4a..d625e539fb9 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HeadersAdaptorInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HeadersAdaptorInstrumentation.java @@ -8,19 +8,16 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -71,85 +68,76 @@ public void methodAdvice(MethodTransformer transformer) { className + "$NamesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterGet( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_HEADER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_HEADER_VALUE, name); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAllAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterGetAll( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final Collection result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Collection result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { final String headerName = name == null ? null : name.toString(); for (final String value : result) { - propagation.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, headerName); + propagation.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, headerName); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class EntriesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterEntries( @Advice.This final Object self, - @Advice.Return final List> result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final List> result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { final Set names = new HashSet<>(); for (Map.Entry entry : result) { final String name = entry.getKey(); final String value = entry.getValue(); if (names.add(name)) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); } - propagation.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + propagation.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class NamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_NAME) public static void afterNames( - @Advice.This final Object self, - @Advice.Return final Set result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Object self, @Advice.Return final Set result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { for (final String name : result) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/Http2ServerRequestInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/Http2ServerRequestInstrumentation.java index 0707bbc7d63..6191d41e44d 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/Http2ServerRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/Http2ServerRequestInstrumentation.java @@ -6,16 +6,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -41,7 +38,6 @@ public void methodAdvice(MethodTransformer transformer) { Http2ServerRequestInstrumentation.class.getName() + "$HeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class HeadersAdvice { @Advice.OnMethodEnter @@ -55,14 +51,13 @@ public static void onEnter( @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( @Advice.Local("beforeHeaders") final Object beforeHeaders, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeHeaders != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HttpServerRequestInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HttpServerRequestInstrumentation.java index 4e580a6bf37..a0bd1b0c332 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HttpServerRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/core/HttpServerRequestInstrumentation.java @@ -7,16 +7,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -42,7 +39,6 @@ public void methodAdvice(MethodTransformer transformer) { HttpServerRequestInstrumentation.class.getName() + "$HeadersAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class HeadersAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @@ -56,14 +52,13 @@ public static void onEnter( @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void onExit( @Advice.Local("beforeHeaders") final Object beforeHeaders, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeHeaders != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_HEADER_VALUE); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/CookieImplInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/CookieImplInstrumentation.java index 805d5b3f049..43e841efd52 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/CookieImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/CookieImplInstrumentation.java @@ -7,19 +7,16 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import io.vertx.ext.web.Cookie; import net.bytebuddy.asm.Advice; @@ -56,37 +53,31 @@ public void methodAdvice(final MethodTransformer transformer) { isMethod().and(named("getValue")).and(takesArguments(0)), className + "$GetValueAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetNameAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_NAME) public static void afterGetName( - @Advice.This final Cookie self, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Cookie self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetValueAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) public static void afterGetValue( - @Advice.This final Cookie self, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Cookie self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { // TODO calling self.getName() actually taints the name of the cookie - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted( - ctx, result, self, SourceTypes.REQUEST_COOKIE_VALUE, self.getName()); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, self, SourceTypes.REQUEST_COOKIE_VALUE, self.getName()); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/IastRoutingContextImplInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/IastRoutingContextImplInstrumentation.java index a7228fb20c8..fa7e7e851fe 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/IastRoutingContextImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/IastRoutingContextImplInstrumentation.java @@ -7,13 +7,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Sink; @@ -22,6 +18,7 @@ import datadog.trace.api.iast.VulnerabilityTypes; import datadog.trace.api.iast.propagation.PropagationModule; import datadog.trace.api.iast.sink.UnvalidatedRedirectModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Set; import net.bytebuddy.asm.Advice; @@ -56,32 +53,28 @@ public void methodAdvice(final MethodTransformer transformer) { className + "$RerouteAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class CookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onCookies( - @Advice.Return final Set cookies, @ActiveRequestContext RequestContext reqCtx) { + public static void onCookies(@Advice.Return final Set cookies) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null && cookies != null && !cookies.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Object cookie : cookies) { - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetCookieAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onGetCookie( - @Advice.Return final Object cookie, @ActiveRequestContext RequestContext reqCtx) { + public static void onGetCookie(@Advice.Return final Object cookie) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/PathParameterPublishingHelper.java b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/PathParameterPublishingHelper.java index c59d09035a3..ec31d87aa0a 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/PathParameterPublishingHelper.java +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/PathParameterPublishingHelper.java @@ -13,6 +13,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.util.Map; @@ -66,14 +67,14 @@ public static Throwable publishParams(Map params) { if (iastRequestContext != null) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { + final TaintedObjects to = iastRequestContext.getTaintedObjects(); for (Map.Entry e : params.entrySet()) { String parameterName = e.getKey(); String value = e.getValue(); if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/BufferInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/BufferInstrumentationTest.groovy index 9d7992d9e37..e5d99d48656 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/BufferInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/BufferInstrumentationTest.groovy @@ -1,10 +1,15 @@ package core import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source +import datadog.trace.api.iast.taint.TaintedObjects +import datadog.trace.bootstrap.instrumentation.api.AgentTracer +import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic import io.vertx.core.buffer.Buffer import io.vertx.core.buffer.impl.BufferImpl @@ -12,6 +17,16 @@ import io.vertx.core.buffer.impl.BufferImpl @CompileDynamic class BufferInstrumentationTest extends AgentTestRunner { + private Object iastCtx + private Object to + + void setup() { + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } + } + @Override protected void configurePreAgent() { injectSysConfig('dd.iast.enabled', 'true') @@ -24,10 +39,12 @@ class BufferInstrumentationTest extends AgentTestRunner { final buffer = taintedInstance(SourceTypes.REQUEST_BODY) when: - method.call(buffer) + runUnderIastTrace { + method.call(buffer) + } then: - 1 * module.taintStringIfTainted(_, buffer) + 1 * module.taintObjectIfTainted(to, _, buffer) where: methodName | method @@ -43,10 +60,12 @@ class BufferInstrumentationTest extends AgentTestRunner { final tainted = taintedInstance(SourceTypes.REQUEST_BODY) when: - method.call(buffer, tainted) + runUnderIastTrace { + method.call(buffer, tainted) + } then: - 1 * module.taintObjectIfTainted(buffer, tainted) + 1 * module.taintObjectIfTainted(to, buffer, tainted) where: methodName | method @@ -57,11 +76,21 @@ class BufferInstrumentationTest extends AgentTestRunner { private Buffer taintedInstance(final byte origin) { final buffer = new BufferImpl('Hello World!') if (buffer instanceof Taintable) { - final source = Mock(Taintable.Source) { + final source = Mock(Source) { getOrigin() >> origin } (buffer as Taintable).$$DD$setSource(source) } return buffer } + + protected E runUnderIastTrace(Closure cl) { + final ddctx = new TagContext().withRequestContextDataIast(iastCtx) + final span = TEST_TRACER.startSpan("test", "test-iast-span", ddctx) + try { + return AgentTracer.activateSpan(span).withCloseable(cl) + } finally { + span.finish() + } + } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/CaseInsensitiveHeadersInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/CaseInsensitiveHeadersInstrumentationTest.groovy index 6aa720abbd1..d51e4dd66f7 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/CaseInsensitiveHeadersInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/CaseInsensitiveHeadersInstrumentationTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic @@ -16,6 +17,7 @@ import org.junit.Assume class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -23,7 +25,10 @@ class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'test that get() is instrumented'() { @@ -37,7 +42,7 @@ class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.get('key') } then: - 1 * module.taintStringIfTainted(iastCtx, 'value', headers, SourceTypes.REQUEST_PARAMETER_VALUE, 'key') + 1 * module.taintObjectIfTainted(to, 'value', headers, SourceTypes.REQUEST_PARAMETER_VALUE, 'key') } void 'test that getAll() is instrumented'() { @@ -51,16 +56,16 @@ class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'value1', SourceTypes.REQUEST_PARAMETER_VALUE, 'key') - 1 * module.taintString(iastCtx, 'value2', SourceTypes.REQUEST_PARAMETER_VALUE, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'value1', SourceTypes.REQUEST_PARAMETER_VALUE, 'key') + 1 * module.taintObject(to, 'value2', SourceTypes.REQUEST_PARAMETER_VALUE, 'key') } void 'test that names() is instrumented'() { @@ -74,15 +79,15 @@ class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'key', SourceTypes.REQUEST_PARAMETER_NAME, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'key', SourceTypes.REQUEST_PARAMETER_NAME, 'key') } void 'test that entries() is instrumented'() { @@ -98,19 +103,19 @@ class CaseInsensitiveHeadersInstrumentationTest extends AgentTestRunner { final result = runUnderIastTrace { headers.entries() } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.entries() } then: - 1 * module.isTainted(iastCtx, headers) >> { true } + 1 * module.isTainted(to, headers) >> { true } result.collect { it.key }.unique().each { - 1 * module.taintString(iastCtx, it, SourceTypes.REQUEST_PARAMETER_NAME, it) + 1 * module.taintObject(to, it, SourceTypes.REQUEST_PARAMETER_NAME, it) } result.each { - 1 * module.taintString(iastCtx, it.value, SourceTypes.REQUEST_PARAMETER_VALUE, it.key) + 1 * module.taintObject(to, it.value, SourceTypes.REQUEST_PARAMETER_VALUE, it.key) } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/HeadersAdaptorInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/HeadersAdaptorInstrumentationTest.groovy index 7509ed00129..5b73e2f9a7e 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/HeadersAdaptorInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/core/HeadersAdaptorInstrumentationTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic @@ -19,6 +20,7 @@ import org.junit.Assume class HeadersAdaptorInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -26,7 +28,10 @@ class HeadersAdaptorInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'test that #name get() is instrumented'() { @@ -39,7 +44,7 @@ class HeadersAdaptorInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.get('key') } then: - 1 * module.taintStringIfTainted(iastCtx, 'value', headers, SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.taintObjectIfTainted(to, 'value', headers, SourceTypes.REQUEST_HEADER_VALUE, 'key') where: headers | name @@ -57,16 +62,16 @@ class HeadersAdaptorInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'value1', SourceTypes.REQUEST_HEADER_VALUE, 'key') - 1 * module.taintString(iastCtx, 'value2', SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'value1', SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.taintObject(to, 'value2', SourceTypes.REQUEST_HEADER_VALUE, 'key') where: headers | name @@ -84,15 +89,15 @@ class HeadersAdaptorInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'key', SourceTypes.REQUEST_HEADER_NAME, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'key', SourceTypes.REQUEST_HEADER_NAME, 'key') where: headers | name @@ -112,19 +117,19 @@ class HeadersAdaptorInstrumentationTest extends AgentTestRunner { final result = runUnderIastTrace { headers.entries() } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.entries() } then: - 1 * module.isTainted(iastCtx, headers) >> { true } + 1 * module.isTainted(to, headers) >> { true } result.collect { it.key }.unique().each { - 1 * module.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_NAME, it) + 1 * module.taintObject(to, it, SourceTypes.REQUEST_HEADER_NAME, it) } result.each { - 1 * module.taintString(iastCtx, it.value, SourceTypes.REQUEST_HEADER_VALUE, it.key) + 1 * module.taintObject(to, it.value, SourceTypes.REQUEST_HEADER_VALUE, it.key) } where: diff --git a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/server/IastSourceTest.groovy b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/server/IastSourceTest.groovy index 592e2d7fa06..17fa08d39ad 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/server/IastSourceTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-3.4/src/test/groovy/server/IastSourceTest.groovy @@ -1,9 +1,9 @@ package server -import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import groovy.transform.CompileDynamic import io.vertx.core.AbstractVerticle import io.vertx.core.MultiMap @@ -27,7 +27,7 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - (1.._) * module.taintObject(_ as IastContext, _, SourceTypes.REQUEST_COOKIE_VALUE) + (1.._) * module.taintObject(_ as TaintedObjects, _, SourceTypes.REQUEST_COOKIE_VALUE) } void 'test that getCookie is instrumented'() { @@ -41,7 +41,7 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - (1.._) * module.taintObject(_ as IastContext, _, SourceTypes.REQUEST_COOKIE_VALUE) + (1.._) * module.taintObject(_ as TaintedObjects, _, SourceTypes.REQUEST_COOKIE_VALUE) } void 'test that cookie getName is instrumented'() { @@ -55,7 +55,7 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintStringIfTainted(_ as IastContext, 'cookieName', _, SourceTypes.REQUEST_COOKIE_NAME, 'cookieName') + 1 * module.taintObjectIfTainted(_ as TaintedObjects, 'cookieName', _, SourceTypes.REQUEST_COOKIE_NAME, 'cookieName') } void 'test that cookie getValue is instrumented'() { @@ -69,8 +69,8 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintStringIfTainted(_ as IastContext, 'cookieName', _, SourceTypes.REQUEST_COOKIE_NAME, 'cookieName') - 1 * module.taintStringIfTainted(_ as IastContext, 'cookieValue', _, SourceTypes.REQUEST_COOKIE_VALUE, 'cookieName') + 1 * module.taintObjectIfTainted(_ as TaintedObjects, 'cookieName', _, SourceTypes.REQUEST_COOKIE_NAME, 'cookieName') + 1 * module.taintObjectIfTainted(_ as TaintedObjects, 'cookieValue', _, SourceTypes.REQUEST_COOKIE_VALUE, 'cookieName') } void 'test that headers() is instrumented'() { @@ -84,7 +84,7 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintObject(_ as IastContext, _, SourceTypes.REQUEST_HEADER_VALUE) + 1 * module.taintObject(_ as TaintedObjects, _, SourceTypes.REQUEST_HEADER_VALUE) } void 'test that params() is instrumented'() { @@ -98,7 +98,7 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintObject(_ as IastContext, _, SourceTypes.REQUEST_PARAMETER_VALUE) + 1 * module.taintObject(_ as TaintedObjects, _, SourceTypes.REQUEST_PARAMETER_VALUE) } void 'test that formAttributes() is instrumented'() { @@ -113,9 +113,9 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintObject(_ as IastContext, _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE) // once for formAttributes() - 1 * module.taintObject(_ as IastContext, _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE) // once for params() - 1 * module.taintStringIfTainted(_ as IastContext, 'form', _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE, 'formAttribute') + 1 * module.taintObject(_ as TaintedObjects, _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE) // once for formAttributes() + 1 * module.taintObject(_ as TaintedObjects, _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE) // once for params() + 1 * module.taintObjectIfTainted(_ as TaintedObjects, 'form', _ as MultiMap, SourceTypes.REQUEST_PARAMETER_VALUE, 'formAttribute') } void 'test that handleData()/onData() is instrumented'() { @@ -130,8 +130,8 @@ class IastSourceTest extends IastVertx34Server { client.newCall(request).execute() then: - 1 * module.taintObject(_ as IastContext, _ as Buffer, SourceTypes.REQUEST_BODY) - 1 * module.taintStringIfTainted('{ "my_key": "my_value" }', _ as Buffer) + 1 * module.taintObject(_ as TaintedObjects, _ as Buffer, SourceTypes.REQUEST_BODY) + 1 * module.taintObjectIfTainted(_ as TaintedObjects, '{ "my_key": "my_value" }', _ as Buffer) } diff --git a/dd-java-agent/instrumentation/vertx-web-3.5/src/main/java/datadog/trace/instrumentation/vertx_3_5/core/VertxHttpHeadersInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-3.5/src/main/java/datadog/trace/instrumentation/vertx_3_5/core/VertxHttpHeadersInstrumentation.java index d5c3c4c957d..2f136ceee4a 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.5/src/main/java/datadog/trace/instrumentation/vertx_3_5/core/VertxHttpHeadersInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-3.5/src/main/java/datadog/trace/instrumentation/vertx_3_5/core/VertxHttpHeadersInstrumentation.java @@ -7,19 +7,16 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -77,84 +74,75 @@ public void methodAdvice(MethodTransformer transformer) { className + "$NamesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterGet( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - propagation.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_HEADER_VALUE, name); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + propagation.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_HEADER_VALUE, name); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAllAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterGetAll( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final Collection result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Collection result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { for (final String value : result) { - propagation.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + propagation.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class EntriesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) public static void afterEntries( @Advice.This final Object self, - @Advice.Return final List> result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final List> result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { final Set names = new HashSet<>(); for (final Map.Entry entry : result) { final String name = entry.getKey(); final String value = entry.getValue(); if (names.add(name)) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); } - propagation.taintString(ctx, value, SourceTypes.REQUEST_HEADER_VALUE, name); + propagation.taintObject(to, value, SourceTypes.REQUEST_HEADER_VALUE, name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class NamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_NAME) public static void afterNames( - @Advice.This final Object self, - @Advice.Return final Set result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Object self, @Advice.Return final Set result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - if (propagation.isTainted(ctx, self)) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (propagation.isTainted(to, self)) { for (final String name : result) { - propagation.taintString(ctx, name, SourceTypes.REQUEST_HEADER_NAME, name); + propagation.taintObject(to, name, SourceTypes.REQUEST_HEADER_NAME, name); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-3.5/src/test/groovy/core/VertxHttpHeadersInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-3.5/src/test/groovy/core/VertxHttpHeadersInstrumentationTest.groovy index 3f8dbd2f247..7021309f919 100644 --- a/dd-java-agent/instrumentation/vertx-web-3.5/src/test/groovy/core/VertxHttpHeadersInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-3.5/src/test/groovy/core/VertxHttpHeadersInstrumentationTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic @@ -15,6 +16,7 @@ import io.vertx.core.http.impl.headers.VertxHttpHeaders class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -22,7 +24,10 @@ class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'test that get() is instrumented'() { @@ -36,7 +41,7 @@ class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.get('key') } then: - 1 * module.taintStringIfTainted(iastCtx, 'value', headers, SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.taintObjectIfTainted(to, 'value', headers, SourceTypes.REQUEST_HEADER_VALUE, 'key') } void 'test that getAll() is instrumented'() { @@ -50,16 +55,16 @@ class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.getAll('key') } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'value1', SourceTypes.REQUEST_HEADER_VALUE, 'key') - 1 * module.taintString(iastCtx, 'value2', SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'value1', SourceTypes.REQUEST_HEADER_VALUE, 'key') + 1 * module.taintObject(to, 'value2', SourceTypes.REQUEST_HEADER_VALUE, 'key') } void 'test that names() is instrumented'() { @@ -73,15 +78,15 @@ class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { false } + 1 * module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.names() } then: - 1 * module.isTainted(iastCtx, headers) >> { true } - 1 * module.taintString(iastCtx, 'key', SourceTypes.REQUEST_HEADER_NAME, 'key') + 1 * module.isTainted(to, headers) >> { true } + 1 * module.taintObject(to, 'key', SourceTypes.REQUEST_HEADER_NAME, 'key') } void 'test that entries() is instrumented'() { @@ -95,19 +100,19 @@ class VertxHttpHeadersInstrumentationTest extends AgentTestRunner { final result = runUnderIastTrace { headers.entries() } then: - module.isTainted(iastCtx, headers) >> { false } + module.isTainted(to, headers) >> { false } 0 * _ when: runUnderIastTrace { headers.entries() } then: - module.isTainted(iastCtx, headers) >> { true } + module.isTainted(to, headers) >> { true } result.collect { it.key }.unique().each { - (1.._) * module.taintString(iastCtx, it, SourceTypes.REQUEST_HEADER_NAME, it) // entries relies on names() on some impls + (1.._) * module.taintObject(to, it, SourceTypes.REQUEST_HEADER_NAME, it) // entries relies on names() on some impls } result.each { - 1 * module.taintString(iastCtx, it.value, SourceTypes.REQUEST_HEADER_VALUE, it.key) + 1 * module.taintObject(to, it.value, SourceTypes.REQUEST_HEADER_VALUE, it.key) } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/AbstractHttpServerRequestInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/AbstractHttpServerRequestInstrumentation.java index 0aea98c6435..cf1a5579396 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/AbstractHttpServerRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/AbstractHttpServerRequestInstrumentation.java @@ -9,17 +9,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Set; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; @@ -64,7 +61,6 @@ public void methodAdvice(final MethodTransformer transformer) { className + "$GetCookieAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class ParamsAdvice { @Advice.OnMethodEnter @@ -78,20 +74,18 @@ public static void onEnter( @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( @Advice.Local("beforeParams") final Object beforeParams, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeParams != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class AttributesAdvice { @Advice.OnMethodEnter @@ -105,77 +99,68 @@ public static void onEnter( @Source(SourceTypes.REQUEST_PARAMETER_VALUE) public static void onExit( @Advice.Local("beforeAttributes") final Object beforeAttributes, - @Advice.Return final Object multiMap, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Object multiMap) { // only taint the map the first time if (beforeAttributes != multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_PARAMETER_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class HeadersAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_HEADER_VALUE) - public static void onExit( - @Advice.Return final Object multiMap, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Object multiMap) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, multiMap, SourceTypes.REQUEST_HEADER_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, multiMap, SourceTypes.REQUEST_HEADER_VALUE); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class DataAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) @Source(SourceTypes.REQUEST_BODY) - public static void onExit( - @Advice.Argument(0) final Object data, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Argument(0) final Object data) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, data, SourceTypes.REQUEST_BODY); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, data, SourceTypes.REQUEST_BODY); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class CookiesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onExit( - @Advice.Return final Set cookies, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Set cookies) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null && cookies != null && !cookies.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); + final TaintedObjects to = IastContext.Provider.taintedObjects(); for (final Object cookie : cookies) { - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetCookieAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) - public static void onExit( - @Advice.Return final Object cookie, @ActiveRequestContext RequestContext reqCtx) { + public static void onExit(@Advice.Return final Object cookie) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintObject(ctx, cookie, SourceTypes.REQUEST_COOKIE_VALUE); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObject(to, cookie, SourceTypes.REQUEST_COOKIE_VALUE); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/BufferInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/BufferInstrumentation.java index 8bb3ab4b142..882d8b5c53a 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/BufferInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/BufferInstrumentation.java @@ -12,9 +12,11 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; +import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import net.bytebuddy.asm.Advice; /** Propagation is way easier in io.vertx.core.buffer.impl.BufferImpl than in io.netty.Buffer */ @@ -64,7 +66,8 @@ public static class ToStringAdvice { public static void get(@Advice.This final Object self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintStringIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self); } } } @@ -75,7 +78,8 @@ public static class GetByteBuffAdvice { public static void get(@Advice.This final Object self, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(result, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self); } } } @@ -87,7 +91,8 @@ public static void get( @Advice.Argument(0) final Object buffer, @Advice.Return final Object result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - module.taintObjectIfTainted(result, buffer); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, buffer); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/MultiMapInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/MultiMapInstrumentation.java index 44e780298ea..5238a4e7e7d 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/MultiMapInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/core/MultiMapInstrumentation.java @@ -7,19 +7,16 @@ import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Propagation; -import datadog.trace.api.iast.Taintable.Source; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -72,60 +69,54 @@ public void methodAdvice(MethodTransformer transformer) { className + "$NamesAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation public static void afterGet( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final String result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - final Source source = propagation.findSource(ctx, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + final Source source = propagation.findSource(to, self); if (source != null) { - propagation.taintString(ctx, result, source.getOrigin(), name); + propagation.taintObject(to, result, source.getOrigin(), name); } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetAllAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation public static void afterGetAll( @Advice.This final Object self, @Advice.Argument(0) final CharSequence name, - @Advice.Return final Collection result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final Collection result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - final Source source = propagation.findSource(ctx, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + final Source source = propagation.findSource(to, self); if (source != null) { for (final String value : result) { - propagation.taintString(ctx, value, source.getOrigin(), name); + propagation.taintObject(to, value, source.getOrigin(), name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class EntriesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation public static void afterEntries( @Advice.This final Object self, - @Advice.Return final List> result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.Return final List> result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - final Source source = propagation.findSource(ctx, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + final Source source = propagation.findSource(to, self); if (source != null) { final byte nameOrigin = namedSource(source.getOrigin()); final Set keys = new HashSet<>(); @@ -133,31 +124,28 @@ public static void afterEntries( final String name = entry.getKey(); final String value = entry.getValue(); if (keys.add(name)) { - propagation.taintString(ctx, name, nameOrigin, name); + propagation.taintObject(to, name, nameOrigin, name); } - propagation.taintString(ctx, value, source.getOrigin(), name); + propagation.taintObject(to, value, source.getOrigin(), name); } } } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class NamesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Propagation public static void afterNames( - @Advice.This final Object self, - @Advice.Return final Set result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Object self, @Advice.Return final Set result) { final PropagationModule propagation = InstrumentationBridge.PROPAGATION; if (propagation != null && result != null && !result.isEmpty()) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - final Source source = propagation.findSource(ctx, self); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + final Source source = propagation.findSource(to, self); if (source != null) { final byte nameOrigin = namedSource(source.getOrigin()); for (final String name : result) { - propagation.taintString(ctx, name, nameOrigin, name); + propagation.taintObject(to, name, nameOrigin, name); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/CookieImplInstrumentation.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/CookieImplInstrumentation.java index b391d49ad7a..22ab1a7bd2e 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/CookieImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/CookieImplInstrumentation.java @@ -6,19 +6,16 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import com.google.auto.service.AutoService; -import datadog.trace.advice.ActiveRequestContext; -import datadog.trace.advice.RequiresRequestContext; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.bytebuddy.iast.TaintableVisitor; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.gateway.RequestContext; -import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.Source; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import io.vertx.core.http.Cookie; import net.bytebuddy.asm.Advice; @@ -54,36 +51,30 @@ public void methodAdvice(final MethodTransformer transformer) { isMethod().and(named("getValue")).and(takesArguments(0)), className + "$GetValueAdvice"); } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetNameAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_NAME) public static void afterGetName( - @Advice.This final Cookie self, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Cookie self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted(ctx, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted(to, result, self, SourceTypes.REQUEST_COOKIE_NAME, result); } } } - @RequiresRequestContext(RequestContextSlot.IAST) public static class GetValueAdvice { @Advice.OnMethodExit(suppress = Throwable.class) @Source(SourceTypes.REQUEST_COOKIE_VALUE) public static void afterGetValue( - @Advice.This final Cookie self, - @Advice.Return final String result, - @ActiveRequestContext RequestContext reqCtx) { + @Advice.This final Cookie self, @Advice.Return final String result) { final PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { - final IastContext ctx = reqCtx.getData(RequestContextSlot.IAST); - module.taintStringIfTainted( - ctx, result, self, SourceTypes.REQUEST_COOKIE_VALUE, self.getName()); + final TaintedObjects to = IastContext.Provider.taintedObjects(); + module.taintObjectIfTainted( + to, result, self, SourceTypes.REQUEST_COOKIE_VALUE, self.getName()); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/PathParameterPublishingHelper.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/PathParameterPublishingHelper.java index b57650e61b7..3eaba969222 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/PathParameterPublishingHelper.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/PathParameterPublishingHelper.java @@ -13,6 +13,7 @@ import datadog.trace.api.iast.InstrumentationBridge; import datadog.trace.api.iast.SourceTypes; import datadog.trace.api.iast.propagation.PropagationModule; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.util.Map; @@ -64,14 +65,14 @@ public static Throwable publishParams(Map params) { if (iastRequestContext != null) { PropagationModule module = InstrumentationBridge.PROPAGATION; if (module != null) { + final TaintedObjects to = iastRequestContext.getTaintedObjects(); for (Map.Entry e : params.entrySet()) { String parameterName = e.getKey(); String value = e.getValue(); if (parameterName == null || value == null) { continue; // should not happen } - module.taintString( - iastRequestContext, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); + module.taintObject(to, value, SourceTypes.REQUEST_PATH_PARAMETER, parameterName); } } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/BufferInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/BufferInstrumentationTest.groovy index 9d7992d9e37..e5d99d48656 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/BufferInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/BufferInstrumentationTest.groovy @@ -1,10 +1,15 @@ package core import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source +import datadog.trace.api.iast.taint.TaintedObjects +import datadog.trace.bootstrap.instrumentation.api.AgentTracer +import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic import io.vertx.core.buffer.Buffer import io.vertx.core.buffer.impl.BufferImpl @@ -12,6 +17,16 @@ import io.vertx.core.buffer.impl.BufferImpl @CompileDynamic class BufferInstrumentationTest extends AgentTestRunner { + private Object iastCtx + private Object to + + void setup() { + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } + } + @Override protected void configurePreAgent() { injectSysConfig('dd.iast.enabled', 'true') @@ -24,10 +39,12 @@ class BufferInstrumentationTest extends AgentTestRunner { final buffer = taintedInstance(SourceTypes.REQUEST_BODY) when: - method.call(buffer) + runUnderIastTrace { + method.call(buffer) + } then: - 1 * module.taintStringIfTainted(_, buffer) + 1 * module.taintObjectIfTainted(to, _, buffer) where: methodName | method @@ -43,10 +60,12 @@ class BufferInstrumentationTest extends AgentTestRunner { final tainted = taintedInstance(SourceTypes.REQUEST_BODY) when: - method.call(buffer, tainted) + runUnderIastTrace { + method.call(buffer, tainted) + } then: - 1 * module.taintObjectIfTainted(buffer, tainted) + 1 * module.taintObjectIfTainted(to, buffer, tainted) where: methodName | method @@ -57,11 +76,21 @@ class BufferInstrumentationTest extends AgentTestRunner { private Buffer taintedInstance(final byte origin) { final buffer = new BufferImpl('Hello World!') if (buffer instanceof Taintable) { - final source = Mock(Taintable.Source) { + final source = Mock(Source) { getOrigin() >> origin } (buffer as Taintable).$$DD$setSource(source) } return buffer } + + protected E runUnderIastTrace(Closure cl) { + final ddctx = new TagContext().withRequestContextDataIast(iastCtx) + final span = TEST_TRACER.startSpan("test", "test-iast-span", ddctx) + try { + return AgentTracer.activateSpan(span).withCloseable(cl) + } finally { + span.finish() + } + } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/MultiMapInstrumentationTest.groovy b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/MultiMapInstrumentationTest.groovy index 69223b107a1..effec0e68a1 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/MultiMapInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/groovy/core/MultiMapInstrumentationTest.groovy @@ -4,8 +4,9 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.iast.IastContext import datadog.trace.api.iast.InstrumentationBridge import datadog.trace.api.iast.SourceTypes -import datadog.trace.api.iast.Taintable import datadog.trace.api.iast.propagation.PropagationModule +import datadog.trace.api.iast.taint.Source +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.bootstrap.instrumentation.api.TagContext import groovy.transform.CompileDynamic @@ -23,6 +24,7 @@ import static datadog.trace.api.iast.SourceTypes.namedSource class MultiMapInstrumentationTest extends AgentTestRunner { private Object iastCtx + private Object to @Override protected void configurePreAgent() { @@ -30,7 +32,10 @@ class MultiMapInstrumentationTest extends AgentTestRunner { } void setup() { - iastCtx = Stub(IastContext) + to = Stub(TaintedObjects) + iastCtx = Stub(IastContext) { + getTaintedObjects() >> to + } } void 'test that #name get() is instrumented'() { @@ -44,15 +49,15 @@ class MultiMapInstrumentationTest extends AgentTestRunner { runUnderIastTrace { instance.get('key') } then: - 1 * module.findSource(iastCtx, instance) >> { null } + 1 * module.findSource(to, instance) >> { null } 0 * _ when: runUnderIastTrace { instance.get('key') } then: - 1 * module.findSource(iastCtx, instance) >> { mockedSource(origin) } - 1 * module.taintString(iastCtx, 'value', origin, 'key') + 1 * module.findSource(to, instance) >> { mockedSource(origin) } + 1 * module.taintObject(to, 'value', origin, 'key') where: instance << multiMaps() @@ -70,16 +75,16 @@ class MultiMapInstrumentationTest extends AgentTestRunner { runUnderIastTrace { instance.getAll('key') } then: - 1 * module.findSource(iastCtx, instance) >> { null } + 1 * module.findSource(to, instance) >> { null } 0 * _ when: runUnderIastTrace { instance.getAll('key') } then: - 1 * module.findSource(iastCtx, instance) >> { mockedSource(origin) } - 1 * module.taintString(iastCtx, 'value1', origin, 'key') - 1 * module.taintString(iastCtx, 'value2', origin, 'key') + 1 * module.findSource(to, instance) >> { mockedSource(origin) } + 1 * module.taintObject(to, 'value1', origin, 'key') + 1 * module.taintObject(to, 'value2', origin, 'key') where: instance << multiMaps() @@ -97,15 +102,15 @@ class MultiMapInstrumentationTest extends AgentTestRunner { runUnderIastTrace { instance.names() } then: - 1 * module.findSource(iastCtx, instance) >> { null } + 1 * module.findSource(to, instance) >> { null } 0 * _ when: runUnderIastTrace { instance.names() } then: - 1 * module.findSource(iastCtx, instance) >> { mockedSource(origin) } - 1 * module.taintString(iastCtx, 'key', namedSource(origin), 'key') + 1 * module.findSource(to, instance) >> { mockedSource(origin) } + 1 * module.taintObject(to, 'key', namedSource(origin), 'key') where: instance << multiMaps() @@ -125,17 +130,17 @@ class MultiMapInstrumentationTest extends AgentTestRunner { runUnderIastTrace { instance.entries() } then: - 1 * module.findSource(iastCtx, instance) >> { null } + 1 * module.findSource(to, instance) >> { null } 0 * _ when: runUnderIastTrace { instance.entries() } then: - 1 * module.findSource(iastCtx, instance) >> { mockedSource(origin) } - 1 * module.taintString(iastCtx, 'key', namedSource(origin), 'key') - 1 * module.taintString(iastCtx, 'value1', origin, 'key') - 1 * module.taintString(iastCtx, 'value2', origin, 'key') + 1 * module.findSource(to, instance) >> { mockedSource(origin) } + 1 * module.taintObject(to, 'key', namedSource(origin), 'key') + 1 * module.taintObject(to, 'value1', origin, 'key') + 1 * module.taintObject(to, 'value2', origin, 'key') where: instance << multiMaps() @@ -153,7 +158,7 @@ class MultiMapInstrumentationTest extends AgentTestRunner { } private mockedSource(final byte origin) { - return Mock(Taintable.Source) { + return Mock(Source) { getOrigin() >> origin } } diff --git a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/java/server/IastSourcesVerticle.java b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/java/server/IastSourcesVerticle.java index 9964b8909a4..eb81ceaa5dc 100644 --- a/dd-java-agent/instrumentation/vertx-web-4.0/src/test/java/server/IastSourcesVerticle.java +++ b/dd-java-agent/instrumentation/vertx-web-4.0/src/test/java/server/IastSourcesVerticle.java @@ -1,7 +1,7 @@ package server; -import com.datadog.iast.taint.TaintedObjects; import datadog.trace.api.iast.IastContext; +import datadog.trace.api.iast.taint.TaintedObjects; import io.vertx.core.AbstractVerticle; import io.vertx.core.MultiMap; import io.vertx.core.Promise; @@ -137,11 +137,10 @@ public void start(final Promise startPromise) throws Exception { final JsonObject payload = (JsonObject) message.body(); final String name = payload.getString("name"); try { - final IastContext ctx = IastContext.Provider.get(); - if (ctx == null) { + final TaintedObjects to = IastContext.Provider.taintedObjects(); + if (to == null) { throw new IllegalStateException("No IAST context present"); } - final TaintedObjects to = ctx.getTaintedObjects(); final boolean tainted = to.get(name) != null; message.reply(tainted ? "OK" : "NO_OK"); } catch (Throwable e) { diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy index 2c2784ec889..feff63e8540 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpServerTest.groovy @@ -25,6 +25,7 @@ import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot import datadog.trace.api.http.StoredBodySupplier import datadog.trace.api.iast.IastContext +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.api.normalize.SimpleHttpPathNormalizer import datadog.trace.bootstrap.blocking.BlockingActionHelper import datadog.trace.bootstrap.instrumentation.api.AgentTracer @@ -2235,10 +2236,13 @@ abstract class HttpServerTest extends WithHttpServer { class IastIGCallbacks { static class Context implements IastContext { + + final taintedObjects = TaintedObjects.NoOp.INSTANCE + @Nonnull @Override - TO getTaintedObjects() { - throw new UnsupportedOperationException() + TaintedObjects getTaintedObjects() { + taintedObjects } @Override diff --git a/internal-api/src/main/java/datadog/trace/api/iast/IastContext.java b/internal-api/src/main/java/datadog/trace/api/iast/IastContext.java index 28e899a8030..b6214930315 100644 --- a/internal-api/src/main/java/datadog/trace/api/iast/IastContext.java +++ b/internal-api/src/main/java/datadog/trace/api/iast/IastContext.java @@ -2,6 +2,7 @@ import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.api.iast.taint.TaintedObjects; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import java.io.Closeable; @@ -16,7 +17,7 @@ public interface IastContext extends Closeable { * {@code TaintedObject} class from here, we use a dirty generics hack. */ @Nonnull - TO getTaintedObjects(); + TaintedObjects getTaintedObjects(); enum Mode { GLOBAL, @@ -32,16 +33,16 @@ public static void register(@Nonnull final Provider instance) { } /** - * Gets an active IAST context, there are two possibilities: + * Gets the current tainted objects, there are two possibilities: * *
    - *
  • dd.iast.context.mode=GLOBAL: It returns the global IAST context instance + *
  • dd.iast.context.mode=GLOBAL: It returns the global IAST tainted objects instance *
  • dd.iast.context.mode=REQUEST: Fetches the active request context and extracts the IAST - * context, {@code null} if there is no active request context + * tainted objects, {@code null} if there is no active request context *
*/ @Nullable - public abstract IastContext resolve(); + public abstract TaintedObjects resolveTaintedObjects(); /** Builds a new context to be scoped to the request */ public abstract IastContext buildRequestContext(); @@ -50,17 +51,24 @@ public static void register(@Nonnull final Provider instance) { public abstract void releaseRequestContext(@Nonnull IastContext context); /** - * Gets the current active IAST context, if no provider is configured this method defaults to - * fetching the current request context + * Gets the current active tainted objects dictionary, if no provider is configured this method + * defaults to fetching the dictionary included in the current request context * - * @see Provider#resolve() + * @see Provider#taintedObjects() */ @Nullable - public static IastContext get() { + public static TaintedObjects taintedObjects() { if (INSTANCE == null) { - return get(AgentTracer.activeSpan()); + final IastContext ctx = get(); + return ctx == null ? null : ctx.getTaintedObjects(); } - return INSTANCE.resolve(); + return INSTANCE.resolveTaintedObjects(); + } + + /** Gets the current active IAST context */ + @Nullable + public static IastContext get() { + return get(AgentTracer.activeSpan()); } /** Gets the current IAST context associated with the request context inside the span */ diff --git a/internal-api/src/main/java/datadog/trace/api/iast/Taintable.java b/internal-api/src/main/java/datadog/trace/api/iast/Taintable.java index 3b86703d10c..abd32a9d964 100644 --- a/internal-api/src/main/java/datadog/trace/api/iast/Taintable.java +++ b/internal-api/src/main/java/datadog/trace/api/iast/Taintable.java @@ -1,5 +1,6 @@ package datadog.trace.api.iast; +import datadog.trace.api.iast.taint.Source; import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -16,15 +17,6 @@ public interface Taintable { return $$DD$getSource() != null; } - /** Interface to isolate customer classloader from our classes */ - interface Source { - byte getOrigin(); - - String getName(); - - String getValue(); - } - @SuppressForbidden class DebugLogger { private static final Logger LOGGER; diff --git a/internal-api/src/main/java/datadog/trace/api/iast/propagation/PropagationModule.java b/internal-api/src/main/java/datadog/trace/api/iast/propagation/PropagationModule.java index ca54e68ff1b..08b7b7b0c5d 100644 --- a/internal-api/src/main/java/datadog/trace/api/iast/propagation/PropagationModule.java +++ b/internal-api/src/main/java/datadog/trace/api/iast/propagation/PropagationModule.java @@ -1,77 +1,38 @@ package datadog.trace.api.iast.propagation; -import datadog.trace.api.iast.IastContext; import datadog.trace.api.iast.IastModule; -import datadog.trace.api.iast.Taintable.Source; +import datadog.trace.api.iast.taint.Source; +import datadog.trace.api.iast.taint.TaintedObjects; import java.util.function.Predicate; import javax.annotation.Nullable; /** Main API for propagation of tainted values, */ -@SuppressWarnings("unused") public interface PropagationModule extends IastModule { - /** @see #taintObject(IastContext, Object, byte) */ - void taintObject(@Nullable Object target, byte origin); - /** * Taints the object with a source with the selected origin and no name, if target is a char * sequence it will be used as value */ - void taintObject(@Nullable IastContext ctx, @Nullable Object target, byte origin); - - /** @see #taintString(IastContext, String, byte) */ - void taintString(@Nullable String target, byte origin); - - /** @see #taintObject(IastContext, Object, byte) */ - void taintString(@Nullable IastContext ctx, @Nullable String target, byte origin); + void taintObject(@Nullable TaintedObjects to, @Nullable Object target, byte origin); /** * Taints the object with a source with the selected origin and name, if target is a char sequence * it will be used as value */ void taintObject( - @Nullable IastContext ctx, @Nullable Object target, byte origin, @Nullable CharSequence name); - - /** @see #taintObject(IastContext, Object, byte, CharSequence) */ - void taintObject(@Nullable Object target, byte origin, @Nullable CharSequence name); - - /** @see #taintObject(IastContext, Object, byte, CharSequence) */ - void taintString( - @Nullable IastContext ctx, @Nullable String target, byte origin, @Nullable CharSequence name); - - /** @see #taintString(IastContext, String, byte, CharSequence) */ - void taintString(@Nullable String target, byte origin, @Nullable CharSequence name); - - /** @see #taintObject(IastContext, Object, byte, CharSequence, Object) */ - void taintObject( - @Nullable Object target, byte origin, @Nullable CharSequence name, @Nullable Object value); + @Nullable TaintedObjects to, + @Nullable Object target, + byte origin, + @Nullable CharSequence name); /** Taints the object with a source with the selected origin, name and value */ void taintObject( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, byte origin, @Nullable CharSequence name, @Nullable Object value); - /** @see #taintString(IastContext, String, byte, CharSequence, CharSequence) */ - void taintString( - @Nullable String target, - byte origin, - @Nullable CharSequence name, - @Nullable CharSequence value); - - /** @see #taintObject(IastContext, Object, byte, CharSequence, Object) */ - void taintString( - @Nullable IastContext ctx, - @Nullable String target, - byte origin, - @Nullable CharSequence name, - @Nullable CharSequence value); - - /** @see #taintObjectRange(IastContext, Object, byte, int, int) */ - void taintObjectRange(@Nullable Object target, byte origin, int start, int length); - /** * Taints the object with a source with the selected origin, range and no name. If target is a * char sequence it will be used as value. @@ -79,35 +40,14 @@ void taintString( *

If the value is already tainted this method will append a new range. */ void taintObjectRange( - @Nullable IastContext ctx, @Nullable Object target, byte origin, int start, int length); - - /** @see #taintStringRange(IastContext, String, byte, int, int) */ - void taintStringRange(@Nullable String target, byte origin, int start, int length); - - /** @see #taintObjectRange(IastContext, Object, byte, int, int) */ - void taintStringRange( - @Nullable IastContext ctx, @Nullable String target, byte origin, int start, int length); - - /** @see #taintObjectIfTainted(IastContext, Object, Object) */ - void taintObjectIfTainted(@Nullable Object target, @Nullable Object input); + @Nullable TaintedObjects to, @Nullable Object target, byte origin, int start, int length); /** * Taints the object only if the input value is tainted. If tainted, it will use the highest * priority source of the input to taint the object. */ void taintObjectIfTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object input); - - /** @see #taintStringIfTainted(IastContext, String, Object) */ - void taintStringIfTainted(@Nullable String target, @Nullable Object input); - - /** @see #taintObjectIfTainted(IastContext, Object, Object) */ - void taintStringIfTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object input); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, boolean, int) */ - void taintObjectIfTainted( - @Nullable Object target, @Nullable Object input, boolean keepRanges, int mark); + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input); /** * Taints the object only if the input value is tainted. It will try to reuse sources from the @@ -119,33 +59,12 @@ void taintObjectIfTainted( * */ void taintObjectIfTainted( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input, boolean keepRanges, int mark); - /** @see #taintStringIfTainted(IastContext, String, Object, boolean, int) */ - void taintStringIfTainted( - @Nullable String target, @Nullable Object input, boolean keepRanges, int mark); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, boolean, int) */ - void taintStringIfTainted( - @Nullable IastContext ctx, - @Nullable String target, - @Nullable Object input, - boolean keepRanges, - int mark); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, boolean, int) */ - void taintObjectIfRangeTainted( - @Nullable Object target, - @Nullable Object input, - int start, - int length, - boolean keepRanges, - int mark); - /** * Taints the object only if the input value has a tainted range that intersects with the * specified range. It will try to reuse sources from the input value according to: @@ -156,7 +75,7 @@ void taintObjectIfRangeTainted( * */ void taintObjectIfRangeTainted( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input, int start, @@ -164,46 +83,13 @@ void taintObjectIfRangeTainted( boolean keepRanges, int mark); - /** @see #taintStringIfTainted(IastContext, String, Object, boolean, int) */ - void taintStringIfRangeTainted( - @Nullable String target, - @Nullable Object input, - int start, - int length, - boolean keepRanges, - int mark); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, boolean, int) */ - void taintStringIfRangeTainted( - @Nullable IastContext ctx, - @Nullable String target, - @Nullable Object input, - int start, - int length, - boolean keepRanges, - int mark); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte) */ - void taintObjectIfTainted(@Nullable Object target, @Nullable Object input, byte origin); - /** * Taints the object only if the input value is tainted, the resulting value will be tainted using * a source with the specified origin and no name, if target is a char sequence it will be used as * value */ void taintObjectIfTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object input, byte origin); - - /** @see #taintStringIfTainted(IastContext, String, Object, byte) */ - void taintStringIfTainted(@Nullable String target, @Nullable Object input, byte origin); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte) */ - void taintStringIfTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object input, byte origin); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte, CharSequence) */ - void taintObjectIfTainted( - @Nullable Object target, @Nullable Object input, byte origin, @Nullable CharSequence name); + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input, byte origin); /** * Taints the object only if the input value is tainted, the resulting value will be tainted using @@ -211,112 +97,46 @@ void taintObjectIfTainted( * value */ void taintObjectIfTainted( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input, byte origin, @Nullable CharSequence name); - /** @see #taintStringIfTainted(IastContext, String, Object, byte, CharSequence) */ - void taintStringIfTainted( - @Nullable String target, @Nullable Object input, byte origin, @Nullable CharSequence name); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte, CharSequence) */ - void taintStringIfTainted( - @Nullable IastContext ctx, - @Nullable String target, - @Nullable Object input, - byte origin, - @Nullable CharSequence name); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte, CharSequence, Object) */ - void taintObjectIfTainted( - @Nullable Object target, - @Nullable Object input, - byte origin, - @Nullable CharSequence name, - @Nullable Object value); - /** * Taints the object only if the input value is tainted, the resulting value will be tainted using * a source with the specified origin, name and value. */ void taintObjectIfTainted( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object input, byte origin, @Nullable CharSequence name, @Nullable Object value); - /** @see #taintStringIfTainted(IastContext, String, Object, byte, CharSequence, Object) */ - void taintStringIfTainted( - @Nullable String target, - @Nullable Object input, - byte origin, - @Nullable CharSequence name, - @Nullable Object value); - - /** @see #taintObjectIfTainted(IastContext, Object, Object, byte, CharSequence, Object) */ - void taintStringIfTainted( - @Nullable IastContext ctx, - @Nullable String target, - @Nullable Object input, - byte origin, - @Nullable CharSequence name, - @Nullable Object value); - - /** @see #taintObjectIfAnyTainted(IastContext, Object, Object[]) */ - void taintObjectIfAnyTainted(@Nullable Object target, @Nullable Object[] inputs); - /** * Taints the object if any of the inputs is tainted. When a tainted input is found the logic is - * the same as in {@link #taintObjectIfTainted(IastContext, Object, Object)} + * the same as in {@link #taintObjectIfTainted(TaintedObjects, Object, Object)} * - * @see #taintObjectIfTainted(IastContext, Object, Object) + * @see #taintObjectIfTainted(TaintedObjects, Object, Object) */ void taintObjectIfAnyTainted( - @Nullable IastContext ctx, @Nullable Object target, @Nullable Object[] inputs); - - /** @see #taintStringIfAnyTainted(IastContext, String, Object[]) */ - void taintStringIfAnyTainted(@Nullable String target, @Nullable Object[] inputs); - - /** @see #taintObjectIfAnyTainted(IastContext, Object, Object[]) */ - void taintStringIfAnyTainted( - @Nullable IastContext ctx, @Nullable String target, @Nullable Object[] inputs); - - /** @see #taintObjectIfAnyTainted(IastContext, Object, Object[], boolean, int) */ - void taintObjectIfAnyTainted( - @Nullable Object target, @Nullable Object[] inputs, boolean keepRanges, int mark); + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object[] inputs); /** * Taints the object if any of the inputs is tainted. When a tainted input is found the logic is - * the same as in {@link #taintObjectIfTainted(IastContext, Object, Object, boolean, int)} + * the same as in {@link #taintObjectIfTainted(TaintedObjects, Object, Object, boolean, int)} * - * @see #taintObjectIfTainted(IastContext, Object, Object, boolean, int) + * @see #taintObjectIfTainted(TaintedObjects, Object, Object, boolean, int) */ void taintObjectIfAnyTainted( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, @Nullable Object[] inputs, boolean keepRanges, int mark); - /** @see #taintStringIfAnyTainted(IastContext, String, Object[], boolean, int) */ - void taintStringIfAnyTainted( - @Nullable String target, @Nullable Object[] inputs, boolean keepRanges, int mark); - - /** @see #taintObjectIfAnyTainted(IastContext, Object, Object[], boolean, int) */ - void taintStringIfAnyTainted( - @Nullable IastContext ctx, - @Nullable String target, - @Nullable Object[] inputs, - boolean keepRanges, - int mark); - - /** @see #taintObjectDeeply(IastContext, Object, byte, Predicate) */ - int taintObjectDeeply(@Nullable Object target, byte origin, Predicate> classFilter); - /** * Visit the graph of the object and taints all the string properties found using a source with * the selected origin and no name. @@ -325,24 +145,17 @@ void taintStringIfAnyTainted( * @return number of tainted elements */ int taintObjectDeeply( - @Nullable IastContext ctx, + @Nullable TaintedObjects to, @Nullable Object target, byte origin, Predicate> classFilter); - /** @see #isTainted(IastContext, Object) */ - boolean isTainted(@Nullable Object target); - /** Checks if an arbitrary object is tainted */ - boolean isTainted(@Nullable IastContext ctx, @Nullable Object target); - - /** @see #findSource(IastContext, Object) */ - @Nullable - Source findSource(@Nullable Object target); + boolean isTainted(@Nullable TaintedObjects to, @Nullable Object target); /** * Returns the source with the highest priority if the object is tainted, {@code null} otherwise */ @Nullable - Source findSource(@Nullable IastContext ctx, @Nullable Object target); + Source findSource(@Nullable TaintedObjects to, @Nullable Object target); } diff --git a/internal-api/src/main/java/datadog/trace/api/iast/taint/Range.java b/internal-api/src/main/java/datadog/trace/api/iast/taint/Range.java new file mode 100644 index 00000000000..36ba2d85720 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/iast/taint/Range.java @@ -0,0 +1,20 @@ +package datadog.trace.api.iast.taint; + +import datadog.trace.api.iast.util.Ranged; +import javax.annotation.Nonnull; + +public interface Range extends Ranged { + + @Nonnull + Source getSource(); + + int getMarks(); + + Range shift(final int offset); + + Range consolidate(); + + boolean isMarked(int mark); + + boolean isValid(); +} diff --git a/internal-api/src/main/java/datadog/trace/api/iast/taint/Source.java b/internal-api/src/main/java/datadog/trace/api/iast/taint/Source.java new file mode 100644 index 00000000000..0f37d2a12f1 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/iast/taint/Source.java @@ -0,0 +1,20 @@ +package datadog.trace.api.iast.taint; + +import javax.annotation.Nullable; + +public interface Source { + + byte getOrigin(); + + @Nullable + String getName(); + + @Nullable + String getValue(); + + Source attachValue(Object newValue); + + boolean isReference(); + + Object getRawValue(); +} diff --git a/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObject.java b/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObject.java new file mode 100644 index 00000000000..a71680cd2f3 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObject.java @@ -0,0 +1,10 @@ +package datadog.trace.api.iast.taint; + +public interface TaintedObject { + + Object get(); + + Range[] getRanges(); + + void setRanges(final Range[] ranges); +} diff --git a/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObjects.java b/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObjects.java new file mode 100644 index 00000000000..0c1cb2979e0 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/iast/taint/TaintedObjects.java @@ -0,0 +1,57 @@ +package datadog.trace.api.iast.taint; + +import java.util.Collections; +import java.util.Iterator; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public interface TaintedObjects extends Iterable { + + @Nullable + TaintedObject taint(@Nonnull Object obj, @Nonnull Range[] ranges); + + @Nullable + TaintedObject get(@Nonnull Object obj); + + boolean isTainted(@Nonnull Object obj); + + void clear(); + + int count(); + + class NoOp implements TaintedObjects { + + public static final TaintedObjects INSTANCE = new NoOp(); + + @Nullable + @Override + public TaintedObject taint(@Nonnull final Object obj, @Nonnull final Range[] ranges) { + return null; + } + + @Nullable + @Override + public TaintedObject get(@Nonnull final Object obj) { + return null; + } + + @Override + public boolean isTainted(@Nonnull final Object obj) { + return false; + } + + @Override + public void clear() {} + + @Override + public int count() { + return 0; + } + + @Override + @Nonnull + public Iterator iterator() { + return Collections.emptyIterator(); + } + } +} diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/Ranged.java b/internal-api/src/main/java/datadog/trace/api/iast/util/Ranged.java similarity index 98% rename from dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/Ranged.java rename to internal-api/src/main/java/datadog/trace/api/iast/util/Ranged.java index 645fb58cfdc..4d571f304cc 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/util/Ranged.java +++ b/internal-api/src/main/java/datadog/trace/api/iast/util/Ranged.java @@ -1,4 +1,4 @@ -package com.datadog.iast.util; +package datadog.trace.api.iast.util; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; diff --git a/internal-api/src/test/groovy/datadog/trace/api/iast/IastContextTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/iast/IastContextTest.groovy index 7ba4d0b1348..697d7ec590f 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/iast/IastContextTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/iast/IastContextTest.groovy @@ -2,6 +2,7 @@ package datadog.trace.api.iast import datadog.trace.api.gateway.RequestContext import datadog.trace.api.gateway.RequestContextSlot +import datadog.trace.api.iast.taint.TaintedObjects import datadog.trace.bootstrap.instrumentation.api.AgentSpan import datadog.trace.bootstrap.instrumentation.api.AgentTracer import datadog.trace.test.util.DDSpecification @@ -14,7 +15,11 @@ class IastContextTest extends DDSpecification { protected AgentTracer.TracerAPI tracer = Mock(AgentTracer.TracerAPI) - protected IastContext iastCtx = Mock(IastContext) + protected TaintedObjects to = Mock(TaintedObjects) + + protected IastContext iastCtx = Mock(IastContext) { + getTaintedObjects() >> to + } protected RequestContext reqCtx = Mock(RequestContext) { getData(RequestContextSlot.IAST) >> iastCtx @@ -57,15 +62,30 @@ class IastContextTest extends DDSpecification { context == iastCtx } - void 'test get context with provider instance'() { - given: + void 'test get tainted objects'() { + setup: final provider = Mock(IastContext.Provider) - IastContext.Provider.register(provider) + IastContext.Provider.register(null) - when: - IastContext.Provider.get() + when: 'there is an active span' + final taintedObjects = IastContext.Provider.taintedObjects() + + then: + 1 * tracer.activeSpan() >> span + taintedObjects == to + + when: 'there is no active span' + final nullTaintedObjects = IastContext.Provider.taintedObjects() + + then: + 1 * tracer.activeSpan() >> null + nullTaintedObjects == null + + when: 'we define a custom provider' + IastContext.Provider.register(provider) + IastContext.Provider.taintedObjects() then: - 1 * provider.resolve() >> null + 1 * provider.resolveTaintedObjects() } } diff --git a/internal-api/src/test/groovy/datadog/trace/api/iast/taint/TaintedObjectsTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/iast/taint/TaintedObjectsTest.groovy new file mode 100644 index 00000000000..f58df2cd2c6 --- /dev/null +++ b/internal-api/src/test/groovy/datadog/trace/api/iast/taint/TaintedObjectsTest.groovy @@ -0,0 +1,30 @@ +package datadog.trace.api.iast.taint + +import spock.lang.Specification + +class TaintedObjectsTest extends Specification { + + void 'test noop instance'() { + setup: + final to = TaintedObjects.NoOp.INSTANCE + final toTaint = new Object() + + when: + to.taint(toTaint, [] as Range[]) + + then: + to.count() == 0 + + when: + final result = to.isTainted(toTaint) + + then: + !result + + when: + final tainted = to.get(toTaint) + + then: + tainted == null + } +} diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/iast/util/RangedTest.groovy similarity index 61% rename from dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedTest.groovy rename to internal-api/src/test/groovy/datadog/trace/api/iast/util/RangedTest.groovy index 5aae9e64869..8126d896011 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/util/RangedTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/iast/util/RangedTest.groovy @@ -1,4 +1,5 @@ -package com.datadog.iast.util +package datadog.trace.api.iast.util + import spock.lang.Shared import spock.lang.Specification @@ -9,23 +10,54 @@ class RangedTest extends Specification { given: final rangeA = ranged(a) final rangeB = ranged(b) + final shouldIntersect = intersection != null + + when: + final result = rangeA.intersection(rangeB) + + then: + if (intersection == null) { + result == null + } else { + final start = result.start + final end = result.start + result.length + start..end == intersection + } when: final intersects = rangeA.intersects(rangeB) then: - assert intersects == expected: "'${toString(a)}' ${expected ? 'should' : 'should not'} intersect '${toString(b)}'" + assert intersects == shouldIntersect: "'${toString(a)}' ${shouldIntersect ? 'should' : 'should not'} intersect '${toString(b)}'" where: - a | b | expected + a | b | intersection + 4..8 | 0..3 | null + 4..8 | 0..4 | 4..4 + 4..8 | 0..6 | 4..6 + 4..8 | 0..8 | 4..8 + 4..8 | 0..10 | 4..8 + 4..8 | 5..6 | 5..6 + 4..8 | 6..10 | 6..8 + 4..8 | 9..10 | null + } + + void 'test isBefore operation'() { + given: + final rangeA = ranged(a) + final rangeB = ranged(b) + + when: + final result = rangeA.isBefore(rangeB) + + then: + result == before + + where: + a | b | before 4..8 | 0..3 | false - 4..8 | 0..4 | true - 4..8 | 0..6 | true - 4..8 | 0..8 | true - 4..8 | 0..10 | true - 4..8 | 5..6 | true 4..8 | 6..10 | true - 4..8 | 9..10 | false + 4..8 | 4..10 | true } void 'test contains operation'() { @@ -83,10 +115,10 @@ class RangedTest extends Specification { } private static Ranged ranged(final IntRange range) { - return Ranged.build(range.fromInt, range.toInt - range.fromInt + (range.inclusive ? 1 : 0)) + return range == null ? null : Ranged.build(range.fromInt, range.toInt - range.fromInt + (range.inclusive ? 1 : 0)) } private static IntRange intRange(final Ranged range) { - return new IntRange(false, range.start, range.start + range.length) + return range == null ? null : new IntRange(false, range.start, range.start + range.length) } }