Skip to content

Commit 74948a7

Browse files
committed
fix(appsec/jetty): use Request bytecode discriminator for jetty-appsec-11.0
Replace the JAKARTA_PART_REFERENCE classpath check with a _dispatcherType field descriptor check on Request.class bytecode, mirroring the approach already used by jetty-appsec-9.4. The classpath check passes on any Jetty 9.4/10 app that has jakarta.servlet-api as a dependency, causing double-instrumentation of extractContentParameters. The bytecode check is authoritative: in Jetty 11+ Request.class carries _dispatcherType as Ljakarta/servlet/DispatcherType;, while 9.4/10 carry the javax descriptor.
1 parent 0ce4bf1 commit 74948a7

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

dd-java-agent/instrumentation/jetty/jetty-appsec/jetty-appsec-11.0/src/main/java/datadog/trace/instrumentation/jetty11/RequestExtractContentParametersInstrumentation.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,22 @@ public void methodAdvice(MethodTransformer transformer) {
6161
// Discriminates Jetty 11.0.x ([11.0, 12.0)):
6262
// - _contentParameters + extractContentParameters(void) exist in 11.x (excludes Jetty 12
6363
// where org.eclipse.jetty.server.Request was removed)
64-
// - jakarta.servlet.http.Part exists in 11.x classpath (excludes 9.4–10.x which use javax)
64+
// - _dispatcherType: Ljakarta/servlet/DispatcherType; in the Request bytecode (excludes
65+
// Jetty 9.4–10.x where the field descriptor is Ljavax/servlet/DispatcherType;). This check
66+
// is tied to Request.class bytecode, NOT just classpath presence, so it works even when both
67+
// javax.servlet and jakarta.servlet are on the classpath simultaneously.
6568
// NOTE: _multiParts changes type at 11.0.10 (MultiPartFormInputStream → MultiParts); both
6669
// are handled transparently because GetFilenamesAdvice reads it with typing=DYNAMIC.
6770
private static final Reference REQUEST_REFERENCE =
6871
new Reference.Builder("org.eclipse.jetty.server.Request")
6972
.withMethod(new String[0], 0, "extractContentParameters", "V")
7073
.withField(new String[0], 0, "_contentParameters", MULTI_MAP_INTERNAL_NAME)
74+
.withField(new String[0], 0, "_dispatcherType", "Ljakarta/servlet/DispatcherType;")
7175
.build();
7276

73-
private static final Reference JAKARTA_PART_REFERENCE =
74-
new Reference.Builder("jakarta.servlet.http.Part").build();
75-
7677
@Override
7778
public Reference[] additionalMuzzleReferences() {
78-
return new Reference[] {REQUEST_REFERENCE, JAKARTA_PART_REFERENCE};
79+
return new Reference[] {REQUEST_REFERENCE};
7980
}
8081

8182
@RequiresRequestContext(RequestContextSlot.APPSEC)

0 commit comments

Comments
 (0)