From efbb1b72594e84bd75e8a7cf752932bbcaf4fa78 Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Wed, 22 Jan 2025 11:41:25 +0000 Subject: [PATCH 1/2] Replace UUID.randomUUID() with RandomUtils.randomUUID() This avoids a potential side-effect of loading 'java.util.logging' too early when the Amazon Corretto Crypto Provider (ACCP) is plugged into SecureRandom --- .../config/ConfigurationApiImpl.java | 4 ++-- .../datadog/crashtracking/CrashUploader.java | 4 ++-- .../datadog/crashtracking/dto/CrashLog.java | 4 ++-- .../trace/bootstrap/debugger/ProbeId.java | 4 ++-- .../debugger/agent/DebuggerTransformer.java | 4 ++-- .../exception/ExceptionProbeManager.java | 6 +++--- .../com/datadog/debugger/sink/Snapshot.java | 4 ++-- .../com/datadog/iast/taint/TaintedObjects.java | 3 ++- .../appsec/powerwaf/PowerWAFModule.java | 4 ++-- gradle/forbiddenApiFilters/main.txt | 3 +++ .../main/java/datadog/trace/api/Config.java | 3 ++- .../java/datadog/trace/util/RandomUtils.java | 16 ++++++++++++++++ .../datadog/trace/util/RandomUtilsTest.java | 18 ++++++++++++++++++ .../remoteconfig/PollerRequestFactory.java | 8 ++++---- 14 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 internal-api/src/main/java/datadog/trace/util/RandomUtils.java create mode 100644 internal-api/src/test/java/datadog/trace/util/RandomUtilsTest.java diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApiImpl.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApiImpl.java index 3b4f9a22d2d..c89bc7e9813 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApiImpl.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApiImpl.java @@ -22,6 +22,7 @@ import datadog.trace.api.civisibility.telemetry.tag.KnownTestsEnabled; import datadog.trace.api.civisibility.telemetry.tag.RequireGit; import datadog.trace.civisibility.communication.TelemetryListener; +import datadog.trace.util.RandomUtils; import java.io.File; import java.io.IOException; import java.lang.reflect.ParameterizedType; @@ -32,7 +33,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.function.Supplier; import javax.annotation.Nullable; import okhttp3.MediaType; @@ -64,7 +64,7 @@ public class ConfigurationApiImpl implements ConfigurationApi { private final JsonAdapter> changedFilesResponseAdapter; public ConfigurationApiImpl(BackendApi backendApi, CiVisibilityMetricCollector metricCollector) { - this(backendApi, metricCollector, () -> UUID.randomUUID().toString()); + this(backendApi, metricCollector, () -> RandomUtils.randomUUID().toString()); } ConfigurationApiImpl( diff --git a/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/CrashUploader.java b/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/CrashUploader.java index 2421b4a49a2..b3115883aad 100644 --- a/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/CrashUploader.java +++ b/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/CrashUploader.java @@ -16,6 +16,7 @@ import datadog.trace.api.DDTags; import datadog.trace.bootstrap.config.provider.ConfigProvider; import datadog.trace.util.PidHelper; +import datadog.trace.util.RandomUtils; import de.thetaphi.forbiddenapis.SuppressForbidden; import java.io.*; import java.nio.charset.Charset; @@ -28,7 +29,6 @@ import java.util.List; import java.util.Map; import java.util.Scanner; -import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -283,7 +283,7 @@ private RequestBody makeTelemetryRequestBody(@Nonnull String content) throws IOE .name("runtime_id") // this is unknowable at this point because the process has crashed // though we may be able to save it in the tmpdir - .value(UUID.randomUUID().toString()); + .value(RandomUtils.randomUUID().toString()); writer.name("tracer_time").value(Instant.now().getEpochSecond()); writer.name("seq_id").value(1); writer.name("debug").value(true); diff --git a/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/dto/CrashLog.java b/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/dto/CrashLog.java index 05611c76d46..adcc327719e 100644 --- a/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/dto/CrashLog.java +++ b/dd-java-agent/agent-crashtracking/src/main/java/com/datadog/crashtracking/dto/CrashLog.java @@ -3,9 +3,9 @@ import com.squareup.moshi.Json; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; +import datadog.trace.util.RandomUtils; import java.io.IOException; import java.util.Objects; -import java.util.UUID; public final class CrashLog { private static final int VERSION = 0; @@ -17,7 +17,7 @@ public final class CrashLog { ADAPTER = moshi.adapter(CrashLog.class); } - public final String uuid = UUID.randomUUID().toString(); + public final String uuid = RandomUtils.randomUUID().toString(); public final String timestamp; public final boolean incomplete; public final ErrorData error; diff --git a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/ProbeId.java b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/ProbeId.java index d00bb4f0ef7..751ab450fb7 100644 --- a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/ProbeId.java +++ b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/ProbeId.java @@ -1,6 +1,6 @@ package datadog.trace.bootstrap.debugger; -import java.util.UUID; +import datadog.trace.util.RandomUtils; public class ProbeId { private static final String ID_SEPARATOR = ":"; @@ -32,7 +32,7 @@ private ProbeId(String id, int version, String encoded) { } public static ProbeId newId() { - return new ProbeId(UUID.randomUUID().toString(), 0); + return new ProbeId(RandomUtils.randomUUID().toString(), 0); } public String getId() { diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java index 7295bfd4efb..6ce20c880dc 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java @@ -29,6 +29,7 @@ import datadog.trace.bootstrap.debugger.MethodLocation; import datadog.trace.bootstrap.debugger.ProbeId; import datadog.trace.bootstrap.debugger.ProbeImplementation; +import datadog.trace.util.RandomUtils; import datadog.trace.util.Strings; import java.io.FileWriter; import java.io.IOException; @@ -50,7 +51,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; import net.bytebuddy.description.type.TypeDescription; @@ -301,7 +301,7 @@ private byte[] transformTheWorld( if (isMethodIncludedForTransformation(methodNode, classNode, methodNames)) { LogProbe probe = LogProbe.builder() - .probeId(UUID.randomUUID().toString(), 0) + .probeId(RandomUtils.randomUUID().toString(), 0) .where(classNode.name, methodNode.name) .captureSnapshot(false) .build(); diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java index 73a5b9737a9..b37708a3252 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java @@ -8,6 +8,7 @@ import datadog.trace.api.Config; import datadog.trace.bootstrap.debugger.DebuggerContext.ClassNameFilter; import datadog.trace.bootstrap.debugger.ProbeId; +import datadog.trace.util.RandomUtils; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -17,7 +18,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,7 +116,7 @@ void addFingerprint(String fingerprint) { private static ExceptionProbe createMethodProbe( ExceptionProbeManager exceptionProbeManager, Where where, int chainedExceptionIdx) { - String probeId = UUID.randomUUID().toString(); + String probeId = RandomUtils.randomUUID().toString(); return new ExceptionProbe( new ProbeId(probeId, 0), where, null, null, exceptionProbeManager, chainedExceptionIdx); } @@ -159,7 +159,7 @@ public void addSnapshot(Snapshot snapshot) { } ThrowableState state = snapshotsByThrowable.computeIfAbsent( - throwable, key -> new ThrowableState(UUID.randomUUID().toString())); + throwable, key -> new ThrowableState(RandomUtils.randomUUID().toString())); snapshot.setExceptionId(state.getExceptionId()); state.addSnapshot(snapshot); } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java index ce940a77d82..1de96d27c34 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java @@ -6,12 +6,12 @@ import datadog.trace.bootstrap.debugger.CapturedStackFrame; import datadog.trace.bootstrap.debugger.EvaluationError; import datadog.trace.bootstrap.debugger.ProbeImplementation; +import datadog.trace.util.RandomUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.UUID; /** Data class representing all data collected at a probe location */ public class Snapshot { @@ -112,7 +112,7 @@ public void addCaughtExceptions(List throwables) { public String getId() { // lazily generates snapshot id if (id == null) { - id = UUID.randomUUID().toString(); + id = RandomUtils.randomUUID().toString(); } return id; } diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjects.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjects.java index cf3c301926d..bef90743403 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjects.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/taint/TaintedObjects.java @@ -6,6 +6,7 @@ import com.datadog.iast.model.Range; import com.datadog.iast.model.json.TaintedObjectEncoding; import com.datadog.iast.util.Wrapper; +import datadog.trace.util.RandomUtils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -86,7 +87,7 @@ final class TaintedObjectsDebugAdapter implements TaintedObjects, Wrapper Date: Thu, 23 Jan 2025 10:40:45 +0000 Subject: [PATCH 2/2] Add RandomUtils.secureRandomUUID() --- .../main/java/datadog/trace/util/RandomUtils.java | 13 +++++++++++++ .../java/datadog/trace/util/RandomUtilsTest.java | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/internal-api/src/main/java/datadog/trace/util/RandomUtils.java b/internal-api/src/main/java/datadog/trace/util/RandomUtils.java index b17e823630b..e8ccee710b1 100644 --- a/internal-api/src/main/java/datadog/trace/util/RandomUtils.java +++ b/internal-api/src/main/java/datadog/trace/util/RandomUtils.java @@ -1,5 +1,6 @@ package datadog.trace.util; +import de.thetaphi.forbiddenapis.SuppressForbidden; import java.util.Random; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -7,10 +8,22 @@ public final class RandomUtils { private RandomUtils() {} + /** Returns a random UUID. */ public static UUID randomUUID() { Random rnd = ThreadLocalRandom.current(); long msb = (rnd.nextLong() & 0xffff_ffff_ffff_0fffL) | 0x0000_0000_0000_4000L; long lsb = (rnd.nextLong() & 0x3fff_ffff_ffff_ffffL) | 0x8000_0000_0000_0000L; return new UUID(msb, lsb); } + + /** + * Returns a cryptographically strong random UUID. + * + *

Note on some systems this may have a side effect of initializing java.util.logging, so its + * use should be avoided during premain. + */ + @SuppressForbidden + public static UUID secureRandomUUID() { + return UUID.randomUUID(); + } } diff --git a/internal-api/src/test/java/datadog/trace/util/RandomUtilsTest.java b/internal-api/src/test/java/datadog/trace/util/RandomUtilsTest.java index ae18e6a8921..0f5db15b25a 100644 --- a/internal-api/src/test/java/datadog/trace/util/RandomUtilsTest.java +++ b/internal-api/src/test/java/datadog/trace/util/RandomUtilsTest.java @@ -15,4 +15,11 @@ public void testRandomUUIDMatchesSpec() { assertThat(RandomUtils.randomUUID().toString()).matches(VERSION_4_UUID); } } + + @Test + public void testSecureRandomUUIDMatchesSpec() { + for (int i = 0; i < 8; i++) { + assertThat(RandomUtils.secureRandomUUID().toString()).matches(VERSION_4_UUID); + } + } }