diff --git a/.circleci/config.continue.yml.j2 b/.circleci/config.continue.yml.j2 index c8e7e65f205..a63f132ea0c 100644 --- a/.circleci/config.continue.yml.j2 +++ b/.circleci/config.continue.yml.j2 @@ -36,7 +36,8 @@ instrumentation_modules: &instrumentation_modules "dd-java-agent/instrumentation debugger_modules: &debugger_modules "dd-java-agent/agent-debugger|dd-java-agent/agent-bootstrap|dd-java-agent/agent-builder|internal-api|communication|dd-trace-core" profiling_modules: &profiling_modules "dd-java-agent/agent-profiling" -default_system_tests_commit: &default_system_tests_commit 35bb7f9753dc82b7c8e4a8276bf6f0ccad0e5dc3 +default_system_tests_commit: &default_system_tests_commit d2064ebdcf7c6bd1ace2a6efb8fca6fa1a4e7c34 + parameters: nightly: diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Location.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Location.java index 7da1bdd611d..9df76cd392a 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Location.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/Location.java @@ -1,5 +1,6 @@ package com.datadog.iast.model; +import com.squareup.moshi.Json; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import javax.annotation.Nullable; @@ -15,10 +16,15 @@ public final class Location { @Nullable private transient String serviceName; + @Nullable + @Json(name = "class") + private final String className; + private Location( @Nullable final Long spanId, @Nullable final String path, final int line, + @Nullable final String className, @Nullable final String method, @Nullable final String serviceName) { this.spanId = spanId; @@ -26,34 +32,36 @@ private Location( this.line = line; this.method = method; this.serviceName = serviceName; + this.className = className; } public static Location forSpanAndStack( @Nullable final AgentSpan span, final StackTraceElement stack) { return new Location( spanId(span), - stack.getClassName(), + stack.getFileName(), stack.getLineNumber(), + stack.getClassName(), stack.getMethodName(), serviceName(span)); } public static Location forSpanAndClassAndMethod( @Nullable final AgentSpan span, final String clazz, final String method) { - return new Location(spanId(span), clazz, -1, method, serviceName(span)); + return new Location(spanId(span), null, -1, clazz, method, serviceName(span)); } public static Location forSpanAndFileAndLine( @Nullable final AgentSpan span, final String file, final int line) { - return new Location(spanId(span), file, line, null, serviceName(span)); + return new Location(spanId(span), file, line, null, null, serviceName(span)); } public static Location forSpan(@Nullable final AgentSpan span) { - return new Location(spanId(span), null, -1, null, serviceName(span)); + return new Location(spanId(span), null, -1, null, null, serviceName(span)); } public static Location forClassAndMethodAndLine(String clazz, String method, int currentLine) { - return new Location(null, clazz, currentLine, method, null); + return new Location(null, null, currentLine, clazz, method, null); } public long getSpanId() { @@ -79,6 +87,11 @@ public String getServiceName() { return serviceName; } + @Nullable + public String getClassName() { + return className; + } + public void updateSpan(@Nullable final AgentSpan span) { if (span != null) { this.spanId = span.getSpanId(); diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/VulnerabilityType.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/VulnerabilityType.java index 0cc7103a548..72f8d1221f0 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/VulnerabilityType.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/model/VulnerabilityType.java @@ -31,15 +31,9 @@ public interface VulnerabilityType { VulnerabilityType WEAK_HASH = type(VulnerabilityTypes.WEAK_HASH).excludedSources(Builder.DB_EXCLUDED).build(); VulnerabilityType INSECURE_COOKIE = - type(VulnerabilityTypes.INSECURE_COOKIE) - .hash(VulnerabilityType::fileAndLineHash) - .excludedSources(Builder.DB_EXCLUDED) - .build(); + type(VulnerabilityTypes.INSECURE_COOKIE).excludedSources(Builder.DB_EXCLUDED).build(); VulnerabilityType NO_HTTPONLY_COOKIE = - type(VulnerabilityTypes.NO_HTTPONLY_COOKIE) - .hash(VulnerabilityType::fileAndLineHash) - .excludedSources(Builder.DB_EXCLUDED) - .build(); + type(VulnerabilityTypes.NO_HTTPONLY_COOKIE).excludedSources(Builder.DB_EXCLUDED).build(); VulnerabilityType HSTS_HEADER_MISSING = type(VulnerabilityTypes.HSTS_HEADER_MISSING) .hash(VulnerabilityType::serviceHash) @@ -51,10 +45,7 @@ public interface VulnerabilityType { .excludedSources(Builder.DB_EXCLUDED) .build(); VulnerabilityType NO_SAMESITE_COOKIE = - type(VulnerabilityTypes.NO_SAMESITE_COOKIE) - .hash(VulnerabilityType::fileAndLineHash) - .excludedSources(Builder.DB_EXCLUDED) - .build(); + type(VulnerabilityTypes.NO_SAMESITE_COOKIE).excludedSources(Builder.DB_EXCLUDED).build(); VulnerabilityType SQL_INJECTION = type(VulnerabilityTypes.SQL_INJECTION).mark(SQL_INJECTION_MARK).build(); @@ -292,7 +283,7 @@ class Builder { private boolean deduplicable = true; private BitSet excludedSources = new BitSet(); private BiFunction hash = - VulnerabilityType::fileAndLineHash; + VulnerabilityType::classAndLineHash; public Builder(byte type) { this.type = type; @@ -328,14 +319,14 @@ public VulnerabilityType build() { } } - static long fileAndLineHash(final VulnerabilityType type, final Vulnerability vulnerability) { + static long classAndLineHash(final VulnerabilityType type, final Vulnerability vulnerability) { CRC32 crc = new CRC32(); update(crc, type.name()); final Location location = vulnerability.getLocation(); if (location != null) { crc.update(location.getLine()); - if (location.getPath() != null) { - update(crc, location.getPath()); + if (location.getClassName() != null) { + update(crc, location.getClassName()); } if (location.getLine() <= -1 && location.getMethod() != null) { update(crc, location.getMethod()); diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/ReporterTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/ReporterTest.groovy index fdba6f7f157..65bcbe0d59f 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/ReporterTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/ReporterTest.groovy @@ -56,7 +56,7 @@ class ReporterTest extends DDSpecification { final v = new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "fooPath", 1)), new Evidence("MD5") ) @@ -76,8 +76,9 @@ class ReporterTest extends DDSpecification { "location": { "spanId":123456, "line":1, - "path": "foo", - "method": "foo" + "path": "fooPath", + "method": "foo", + "class": "foo" }, "stackId":"1", "type":"WEAK_HASH" @@ -109,7 +110,7 @@ class ReporterTest extends DDSpecification { final v = new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "fooPath", 1)), new Evidence("MD5") ) @@ -127,8 +128,9 @@ class ReporterTest extends DDSpecification { "location": { "spanId":123456, "line":1, - "path": "foo", - "method": "foo" + "path": "fooPath", + "method": "foo", + "class": "foo" }, "type":"WEAK_HASH" } @@ -155,12 +157,12 @@ class ReporterTest extends DDSpecification { final v1 = new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "fooPath1", 1)), new Evidence("MD5") ) final v2 = new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "foo", 2)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "foo", "fooPath2", 2)), new Evidence("MD4") ) @@ -185,8 +187,9 @@ class ReporterTest extends DDSpecification { "location": { "spanId":123456, "line":1, - "path":"foo", - "method": "foo" + "path": "fooPath1", + "method": "foo", + "class": "foo" }, "stackId":"1", "type":"WEAK_HASH" @@ -197,8 +200,9 @@ class ReporterTest extends DDSpecification { "location": { "spanId":123456, "line":2, - "path":"foo", - "method": "foo" + "path": "fooPath2", + "method": "foo", + "class": "foo" }, "stackId":"2", "type":"WEAK_HASH" diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/LocationTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/LocationTest.groovy index 4c496b854ad..ecfad4e4f37 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/LocationTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/model/LocationTest.groovy @@ -17,7 +17,8 @@ class LocationTest extends DDSpecification { then: location.getSpanId() == spanId - location.getPath() == "declaringClass" + location.getPath() == "fileName" + location.getClassName() == "declaringClass" location.getLine() == 42 location.getMethod() == stack.methodName } @@ -35,7 +36,7 @@ class LocationTest extends DDSpecification { then: location.getSpanId() == spanId - location.getPath() == "declaringClass" + location.getClassName() == "declaringClass" location.getLine() == -1 location.getMethod() == methodName } @@ -50,7 +51,7 @@ class LocationTest extends DDSpecification { final location = Location.forClassAndMethodAndLine(declaringClass, methodName, line) then: - location.getPath() == "declaringClass" + location.getClassName() == "declaringClass" location.getLine() == line location.getMethod() == methodName } 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..602af570b0f 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 @@ -66,7 +66,7 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooBar", 1)), new Evidence("MD5") )) @@ -86,7 +86,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "fooBar", + "class": "foo" } } ] @@ -98,7 +99,7 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(null, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(null, new StackTraceElement("foo", "fooMethod", "fooBar", 1)), new Evidence("MD5") )) @@ -117,7 +118,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "location": { "line": 1, "method": "fooMethod", - "path": "foo" + "path": "fooBar", + "class" : "foo" } } ] @@ -132,7 +134,7 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooFile", 1)), new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value"), NOT_MARKED)] as Range[]) )) @@ -155,7 +157,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "fooFile", + "class": "foo" } } ], @@ -177,7 +180,7 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooBar", 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) @@ -204,7 +207,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "fooBar", + "class": "foo" } } ], @@ -231,7 +235,7 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("fooClass", "fooMethod", "foo", 1)), new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.NONE, "key", "value"), NOT_MARKED)] as Range[]) )) @@ -249,12 +253,13 @@ class VulnerabilityEncodingTest extends DDSpecification { {"value": "AD"} ] }, - "hash":1042880134, + "hash":285679096, "location": { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "foo", + "class": "fooClass" } } ], @@ -276,12 +281,12 @@ class VulnerabilityEncodingTest extends DDSpecification { final source = new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key", "value") value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("fooX", "fooMethod", "fooX", 1)), new Evidence("BAD1", [new Range(0, 1, source, NOT_MARKED)] as Range[]) )) value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("fooY", "fooMethod", "fooY", 1)), new Evidence("BAD2", [new Range(0, 1, source, NOT_MARKED)] as Range[]) )) @@ -298,12 +303,13 @@ class VulnerabilityEncodingTest extends DDSpecification { {"value": "AD1"} ] }, - "hash": 1042880134, + "hash": 3008837960, "location": { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "fooX", + "class": "fooX" }, "type": "WEAK_HASH" }, @@ -314,12 +320,13 @@ class VulnerabilityEncodingTest extends DDSpecification { {"value": "AD2"} ] }, - "hash": 1042880134, + "hash": 3293579742, "location": { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "foo", + "class": "fooY" }, "type": "WEAK_HASH" } @@ -342,12 +349,12 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooX", 1)), new Evidence("BAD", [new Range(0, 1, new Source(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)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooY", 1)), new Evidence("BAD", [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED)] as Range[]) )) @@ -369,7 +376,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "class": "foo", + "path": "fooX" }, "type": "WEAK_HASH" }, @@ -385,7 +393,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "class": "foo", + "path": "fooY" }, "type": "WEAK_HASH" } @@ -433,7 +442,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "path": "foo", + "class": "foo" } } ] @@ -448,12 +458,12 @@ class VulnerabilityEncodingTest extends DDSpecification { final value = new VulnerabilityBatch() value.add(new Vulnerability( VulnerabilityType.WEAK_HASH, - Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "foo", 1)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooFile1", 1)), new Evidence(generateLargeString(), [new Range(0, 1, new Source(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)), + Location.forSpanAndStack(span, new StackTraceElement("foo", "fooMethod", "fooFile", 1)), new Evidence(generateLargeString(), [new Range(0, 1, new Source(SourceTypes.REQUEST_PARAMETER_VALUE, "key2", "value"), NOT_MARKED)] as Range[]) )) @@ -472,7 +482,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "class": "foo", + "path": "fooFile1" }, "type": "WEAK_HASH" }, @@ -485,7 +496,8 @@ class VulnerabilityEncodingTest extends DDSpecification { "spanId": 123456, "line": 1, "method": "fooMethod", - "path": "foo" + "class": "foo", + "path": "fooFile" }, "type": "WEAK_HASH" } diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HardcodedSecretModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HardcodedSecretModuleTest.groovy index ee7c446d792..182b2f4bf60 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HardcodedSecretModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/HardcodedSecretModuleTest.groovy @@ -45,7 +45,7 @@ class HardcodedSecretModuleTest extends IastModuleImplTestBase { final evidence = vuln.evidence assert evidence != null assert evidence.value == expectedEvidence - assert vuln.location.path == className + assert vuln.location.className == className assert vuln.location.method == methodName assert vuln.location.line == line } diff --git a/dd-smoke-tests/springboot/src/test/groovy/datadog/smoketest/IastSpringBootSmokeTest.groovy b/dd-smoke-tests/springboot/src/test/groovy/datadog/smoketest/IastSpringBootSmokeTest.groovy index cbc660a19a0..d689b5da887 100644 --- a/dd-smoke-tests/springboot/src/test/groovy/datadog/smoketest/IastSpringBootSmokeTest.groovy +++ b/dd-smoke-tests/springboot/src/test/groovy/datadog/smoketest/IastSpringBootSmokeTest.groovy @@ -47,7 +47,7 @@ class IastSpringBootSmokeTest extends AbstractIastSpringBootTest { vul -> vul.type == 'HARDCODED_SECRET' && vul.location.method == 'hardcodedSecret' - && vul.location.path == 'datadog.smoketest.springboot.controller.HardcodedSecretController' + && vul.location.class == 'datadog.smoketest.springboot.controller.HardcodedSecretController' && vul.location.line == 11 && vul.evidence.value == 'age-secret-key' }