Skip to content

Commit ed1c6a2

Browse files
authored
Merge branch 'master' into INPLAT-614
2 parents 07eb21e + 9519752 commit ed1c6a2

File tree

53 files changed

+1214
-129
lines changed

Some content is hidden

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

53 files changed

+1214
-129
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ variables:
2525
BUILD_JOB_NAME: "build"
2626
DEPENDENCY_CACHE_POLICY: pull
2727
BUILD_CACHE_POLICY: pull
28-
GRADLE_VERSION: "8.5" # must match gradle-wrapper.properties
28+
GRADLE_VERSION: "8.14.3" # must match gradle-wrapper.properties
2929
MAVEN_REPOSITORY_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/maven-central/"
3030
GRADLE_PLUGIN_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/gradle-plugin-portal-proxy/"
3131
BUILDER_IMAGE_VERSION_PREFIX: "v25.06-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")

communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class SharedCommunicationObjects {
3030
public OkHttpClient okHttpClient;
3131
public HttpUrl agentUrl;
3232
public Monitoring monitoring;
33-
private DDAgentFeaturesDiscovery featuresDiscovery;
33+
private volatile DDAgentFeaturesDiscovery featuresDiscovery;
3434
private ConfigurationPoller configurationPoller;
3535

3636
public SharedCommunicationObjects() {
@@ -139,28 +139,34 @@ public void setFeaturesDiscovery(DDAgentFeaturesDiscovery featuresDiscovery) {
139139
}
140140

141141
public DDAgentFeaturesDiscovery featuresDiscovery(Config config) {
142-
if (featuresDiscovery == null) {
143-
createRemaining(config);
144-
featuresDiscovery =
145-
new DDAgentFeaturesDiscovery(
146-
okHttpClient,
147-
monitoring,
148-
agentUrl,
149-
config.isTraceAgentV05Enabled(),
150-
config.isTracerMetricsEnabled());
151-
152-
if (paused) {
153-
// defer remote discovery until remote I/O is allowed
154-
} else {
155-
if (AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) {
156-
featuresDiscovery.discover(); // safe to run on same thread
157-
} else {
158-
// avoid performing blocking I/O operation on application thread
159-
AgentTaskScheduler.INSTANCE.execute(featuresDiscovery::discover);
142+
DDAgentFeaturesDiscovery ret = featuresDiscovery;
143+
if (ret == null) {
144+
synchronized (this) {
145+
if (featuresDiscovery == null) {
146+
createRemaining(config);
147+
ret =
148+
new DDAgentFeaturesDiscovery(
149+
okHttpClient,
150+
monitoring,
151+
agentUrl,
152+
config.isTraceAgentV05Enabled(),
153+
config.isTracerMetricsEnabled());
154+
155+
if (paused) {
156+
// defer remote discovery until remote I/O is allowed
157+
} else {
158+
if (AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) {
159+
ret.discover(); // safe to run on same thread
160+
} else {
161+
// avoid performing blocking I/O operation on application thread
162+
AgentTaskScheduler.INSTANCE.execute(ret::discover);
163+
}
164+
}
165+
featuresDiscovery = ret;
160166
}
161167
}
162168
}
163-
return featuresDiscovery;
169+
return ret;
164170
}
165171

166172
private static final class FixedConfigUrlSupplier implements Supplier<String> {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.datadog.iast;
2+
3+
import datadog.trace.api.gateway.RequestContext;
4+
import datadog.trace.api.gateway.RequestContextSlot;
5+
import java.util.function.BiConsumer;
6+
7+
public class HttpRouteHandler implements BiConsumer<RequestContext, String> {
8+
9+
@Override
10+
public void accept(final RequestContext ctx, final String route) {
11+
final IastRequestContext iastCtx = ctx.getData(RequestContextSlot.IAST);
12+
if (iastCtx != null) {
13+
iastCtx.setRoute(route);
14+
}
15+
}
16+
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class IastRequestContext implements IastContext, HasMetricCollector {
3636
@Nullable private volatile String xForwardedProto;
3737
@Nullable private volatile String contentType;
3838
@Nullable private volatile String authorization;
39+
@Nullable private volatile String route;
3940

4041
/**
4142
* Use {@link IastRequestContext#IastRequestContext(TaintedObjects)} instead as we require more
@@ -121,6 +122,15 @@ public void setAuthorization(final String authorization) {
121122
this.authorization = authorization;
122123
}
123124

125+
@Nullable
126+
public String getRoute() {
127+
return route;
128+
}
129+
130+
public void setRoute(final String route) {
131+
this.route = route;
132+
}
133+
124134
public OverheadContext getOverheadContext() {
125135
return overheadContext;
126136
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public static void start(
122122
registerRequestStartedCallback(ss, addTelemetry, dependencies);
123123
registerRequestEndedCallback(ss, addTelemetry, dependencies);
124124
registerHeadersCallback(ss);
125+
registerHttpRouteCallback(ss);
125126
registerGrpcServerRequestMessageCallback(ss);
126127
maybeApplySecurityControls(instrumentation);
127128
LOGGER.debug("IAST started");
@@ -246,6 +247,10 @@ private static void registerHeadersCallback(final SubscriptionService ss) {
246247
ss.registerCallback(event, handler);
247248
}
248249

250+
private static void registerHttpRouteCallback(final SubscriptionService ss) {
251+
ss.registerCallback(Events.get().httpRoute(), new HttpRouteHandler());
252+
}
253+
249254
private static void registerGrpcServerRequestMessageCallback(final SubscriptionService ss) {
250255
ss.registerCallback(Events.get().grpcServerRequestMessage(), new GrpcRequestMessageHandler());
251256
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/overhead/OverheadController.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public boolean consumeQuota(
233233
Object methodTag = rootSpan.getTag(Tags.HTTP_METHOD);
234234
method = (methodTag == null) ? "" : methodTag.toString();
235235
Object routeTag = rootSpan.getTag(Tags.HTTP_ROUTE);
236-
path = (routeTag == null) ? "" : routeTag.toString();
236+
path = (routeTag == null) ? getHttpRouteFromRequestContext(span) : routeTag.toString();
237237
}
238238
if (!maybeSkipVulnerability(ctx, type, method, path)) {
239239
return operation.consumeQuota(ctx);
@@ -316,6 +316,19 @@ public OverheadContext getContext(@Nullable final AgentSpan span) {
316316
return globalContext;
317317
}
318318

319+
@Nullable
320+
public String getHttpRouteFromRequestContext(@Nullable final AgentSpan span) {
321+
String httpRoute = null;
322+
final RequestContext requestContext = span != null ? span.getRequestContext() : null;
323+
if (requestContext != null) {
324+
IastRequestContext iastRequestContext = requestContext.getData(RequestContextSlot.IAST);
325+
if (iastRequestContext != null) {
326+
httpRoute = iastRequestContext.getRoute();
327+
}
328+
}
329+
return httpRoute == null ? "" : httpRoute;
330+
}
331+
319332
static int computeSamplingParameter(final float pct) {
320333
if (pct >= 100) {
321334
return 100;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.datadog.iast
2+
3+
import datadog.trace.api.gateway.RequestContext
4+
import datadog.trace.api.gateway.RequestContextSlot
5+
import datadog.trace.test.util.DDSpecification
6+
import groovy.transform.CompileDynamic
7+
8+
@CompileDynamic
9+
class HttpRouteHandlerTest extends DDSpecification {
10+
void 'route is set'() {
11+
given:
12+
final handler = new HttpRouteHandler()
13+
final iastCtx = Mock(IastRequestContext)
14+
final ctx = Mock(RequestContext)
15+
ctx.getData(RequestContextSlot.IAST) >> iastCtx
16+
17+
when:
18+
handler.accept(ctx, '/foo')
19+
20+
then:
21+
1 * ctx.getData(RequestContextSlot.IAST) >> iastCtx
22+
1 * iastCtx.setRoute('/foo')
23+
0 * _
24+
}
25+
26+
void 'does nothing when context missing'() {
27+
given:
28+
final handler = new HttpRouteHandler()
29+
final ctx = Mock(RequestContext)
30+
ctx.getData(RequestContextSlot.IAST) >> null
31+
32+
when:
33+
handler.accept(ctx, '/foo')
34+
35+
then:
36+
1 * ctx.getData(RequestContextSlot.IAST) >> null
37+
0 * _
38+
}
39+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class IastSystemTest extends DDSpecification {
6060
1 * ss.registerCallback(Events.get().requestStarted(), _)
6161
1 * ss.registerCallback(Events.get().requestEnded(), _)
6262
1 * ss.registerCallback(Events.get().requestHeader(), _)
63+
1 * ss.registerCallback(Events.get().httpRoute(), _)
6364
1 * ss.registerCallback(Events.get().grpcServerRequestMessage(), _)
6465
0 * _
6566
TestLogCollector.drainCapturedLogs().any { it.message.contains('IAST is starting') }

dd-java-agent/instrumentation/gradle-8.3/src/main/groovy/datadog/trace/instrumentation/gradle/CiVisibilityGradleListenerInjector_8_3.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
package datadog.trace.instrumentation.gradle;
22

3+
import datadog.trace.util.MethodHandles;
4+
import java.lang.invoke.MethodHandle;
35
import java.util.Arrays;
6+
import org.gradle.api.Action;
47
import org.gradle.initialization.ClassLoaderRegistry;
58
import org.gradle.internal.service.DefaultServiceRegistry;
9+
import org.gradle.internal.service.ServiceRegistration;
610
import org.gradle.internal.service.ServiceRegistry;
711
import org.slf4j.Logger;
812
import org.slf4j.LoggerFactory;
913

1014
public class CiVisibilityGradleListenerInjector_8_3 {
1115

16+
private static final MethodHandles METHOD_HANDLES =
17+
new MethodHandles(DefaultServiceRegistry.class.getClassLoader());
18+
private static final MethodHandle REGISTER_SERVICE =
19+
METHOD_HANDLES.method(DefaultServiceRegistry.class, "register", Action.class);
20+
1221
private static final Logger LOGGER =
1322
LoggerFactory.getLogger(CiVisibilityGradleListenerInjector_8_3.class);
1423

@@ -21,8 +30,9 @@ public static void injectCiVisibilityGradleListener(
2130
Class<?> ciVisibilityGradleListener =
2231
CiVisibilityGradleListenerInjector_8_3.loadCiVisibilityGradleListener(
2332
classLoaderRegistry);
24-
buildScopeServices.register(
25-
serviceRegistration -> serviceRegistration.add(ciVisibilityGradleListener));
33+
Action<ServiceRegistration> registrationAction =
34+
serviceRegistration -> serviceRegistration.add(ciVisibilityGradleListener);
35+
METHOD_HANDLES.invoke(REGISTER_SERVICE, buildScopeServices, registrationAction);
2636
} catch (Exception e) {
2737
LOGGER.warn("Could not inject CI Visibility Gradle listener", e);
2838
}

dd-java-agent/instrumentation/gradle-8.3/src/main/groovy/datadog/trace/instrumentation/gradle/GradleBuildScopeServices_8_3_Instrumentation.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import java.util.Set;
1212
import net.bytebuddy.asm.Advice;
1313
import net.bytebuddy.matcher.ElementMatcher;
14+
import org.gradle.internal.service.DefaultServiceRegistry;
1415
import org.gradle.internal.service.ServiceRegistry;
15-
import org.gradle.internal.service.scopes.BuildScopeServices;
1616

1717
@AutoService(InstrumenterModule.class)
1818
public class GradleBuildScopeServices_8_3_Instrumentation extends InstrumenterModule.CiVisibility
@@ -55,10 +55,15 @@ public void methodAdvice(MethodTransformer transformer) {
5555
public static class Construct {
5656
@Advice.OnMethodExit(suppress = Throwable.class)
5757
public static void afterConstructor(
58-
@Advice.This final BuildScopeServices buildScopeServices,
58+
@Advice.This final DefaultServiceRegistry buildScopeServices,
5959
@Advice.Argument(0) final ServiceRegistry parentServices) {
6060
CiVisibilityGradleListenerInjector_8_3.injectCiVisibilityGradleListener(
6161
buildScopeServices, parentServices);
6262
}
6363
}
64+
65+
@Override
66+
public String muzzleDirective() {
67+
return "skipMuzzle";
68+
}
6469
}

0 commit comments

Comments
 (0)