diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/appsec/Bug4304Instrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/appsec/Bug4304Instrumentation.java index b185117f882..7f49b3a4c14 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/appsec/Bug4304Instrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/appsec/Bug4304Instrumentation.java @@ -16,6 +16,7 @@ import datadog.trace.api.gateway.RequestContext; import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.reflect.Field; import java.util.regex.Pattern; import net.bytebuddy.asm.Advice; @@ -92,6 +93,7 @@ public void methodAdvice(MethodTransformer transformer) { static class GraphStageLogicAdvice { @Advice.OnMethodExit(suppress = Throwable.class) + @SuppressForbidden static void after(@Advice.This GraphStageLogic thiz) throws NoSuchFieldException, IllegalAccessException { AgentSpan span = activeSpan(); diff --git a/dd-java-agent/instrumentation/weaver-0.9/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java b/dd-java-agent/instrumentation/weaver-0.9/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java index f28a45f03c5..1debafcd7bf 100644 --- a/dd-java-agent/instrumentation/weaver-0.9/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java +++ b/dd-java-agent/instrumentation/weaver-0.9/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java @@ -5,6 +5,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.reflect.Field; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -43,6 +44,7 @@ public void methodAdvice(MethodTransformer transformer) { public static class SbtTaskCreationAdvice { @Advice.OnMethodExit(suppress = Throwable.class) + @SuppressForbidden public static void onTaskCreation( @Advice.This Object sbtTask, @Advice.FieldValue("taskDef") TaskDef taskDef) { try { diff --git a/gradle/forbiddenApiFilters/main.txt b/gradle/forbiddenApiFilters/main.txt index db69659cb7a..4b8a52c69f8 100644 --- a/gradle/forbiddenApiFilters/main.txt +++ b/gradle/forbiddenApiFilters/main.txt @@ -1,7 +1,7 @@ # loads and instantiates a class which may be inefficient depending on context java.lang.Class#forName(java.lang.String) -# String methods which uses regexes for matching +# String methods which use regexes for matching java.lang.String#split(java.lang.String) java.lang.String#split(java.lang.String,int) java.lang.String#replaceAll(java.lang.String,java.lang.String) @@ -34,6 +34,11 @@ java.lang.System#err java.lang.System#getenv() java.lang.System#getenv(java.lang.String) -#Use jdk LongAdder +# use jdk LongAdder instead of jctools FixedSizeStripedLongCounter @defaultMessage use LongAdder instead of the legacy jctools FixedSizeStripedLongCounter org.jctools.counters.FixedSizeStripedLongCounter + +# avoid methods that mutate final fields +@defaultMessage Avoid using Field::set and MethodHandles.Lookup::unreflectSetter. Java is moving toward integrity by default which restricts final field mutation. More details here: https://openjdk.org/jeps/500. +java.lang.reflect.Field#set(java.lang.Object,java.lang.Object) +java.lang.invoke.MethodHandles$Lookup#unreflectSetter(java.lang.reflect.Field) diff --git a/internal-api/src/main/java/datadog/trace/api/iast/InstrumentationBridge.java b/internal-api/src/main/java/datadog/trace/api/iast/InstrumentationBridge.java index 7c5c9d1ae3f..eb23eebbda5 100644 --- a/internal-api/src/main/java/datadog/trace/api/iast/InstrumentationBridge.java +++ b/internal-api/src/main/java/datadog/trace/api/iast/InstrumentationBridge.java @@ -29,6 +29,7 @@ import datadog.trace.api.iast.sink.XContentTypeModule; import datadog.trace.api.iast.sink.XPathInjectionModule; import datadog.trace.api.iast.sink.XssModule; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -124,6 +125,7 @@ private static M get(final Field field) { } } + @SuppressForbidden private static void set(final Field field, final IastModule module) { try { field.set(null, module); diff --git a/internal-api/src/main/java/datadog/trace/util/MethodHandles.java b/internal-api/src/main/java/datadog/trace/util/MethodHandles.java index bb0f756bf6f..cd2e6e792dd 100644 --- a/internal-api/src/main/java/datadog/trace/util/MethodHandles.java +++ b/internal-api/src/main/java/datadog/trace/util/MethodHandles.java @@ -1,6 +1,7 @@ package datadog.trace.util; import datadog.trace.api.telemetry.LogCollector; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.invoke.MethodHandle; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -65,6 +66,7 @@ public MethodHandle privateFieldSetter(String className, String fieldName) { return clazz != null ? privateFieldSetter(clazz, fieldName) : null; } + @SuppressForbidden public MethodHandle privateFieldSetter(Class clazz, String fieldName) { return AccessController.doPrivileged( (PrivilegedAction) diff --git a/internal-api/src/main/java/datadog/trace/util/UnsafeUtils.java b/internal-api/src/main/java/datadog/trace/util/UnsafeUtils.java index cc0830b68c8..91320caa625 100644 --- a/internal-api/src/main/java/datadog/trace/util/UnsafeUtils.java +++ b/internal-api/src/main/java/datadog/trace/util/UnsafeUtils.java @@ -1,5 +1,6 @@ package datadog.trace.util; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import org.slf4j.Logger; @@ -57,6 +58,7 @@ public static T tryShallowClone(T original) { } } + @SuppressForbidden private static void cloneFields(Class clazz, Object original, Object clone) throws Exception { for (Field field : clazz.getDeclaredFields()) { if ((field.getModifiers() & Modifier.STATIC) != 0) {