-
Notifications
You must be signed in to change notification settings - Fork 292
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve coverage of application vulnerabilities for servlet (#6803)
What Does This Do Get the realPath from the context when HttpServlet#service or javax.servlet.FilterChain#doFilter (This implementation is based on the current tracer instrumentation for servlet) Remove javax.servlet.ServletContext#getRealPath instrumentation Add new Iast Instrumentations for: servlet2 -> javax.servlet.Servlet servlet3 -> javax.servlet.Servlet servlet5 -> jakarta.servlet.Servlet Motivation We noticed that javax.servlet.ServletContext#getRealPath is not always called, so we need to find a more reliable point to check the vulnerabilities Add coverage to servlet 5
- Loading branch information
Showing
15 changed files
with
1,173 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...et/request-2/src/main/java/datadog/trace/instrumentation/servlet2/IastServlet2Advice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package datadog.trace.instrumentation.servlet2; | ||
|
||
import datadog.trace.api.iast.InstrumentationBridge; | ||
import datadog.trace.api.iast.Sink; | ||
import datadog.trace.api.iast.VulnerabilityTypes; | ||
import datadog.trace.api.iast.sink.ApplicationModule; | ||
import datadog.trace.bootstrap.InstrumentationContext; | ||
import javax.servlet.ServletContext; | ||
import javax.servlet.http.HttpServlet; | ||
import net.bytebuddy.asm.Advice; | ||
|
||
public class IastServlet2Advice { | ||
|
||
@Sink(VulnerabilityTypes.APPLICATION) | ||
@Advice.OnMethodExit(suppress = Throwable.class) | ||
public static void onExit(@Advice.This Object servlet) { | ||
final ApplicationModule applicationModule = InstrumentationBridge.APPLICATION; | ||
if (applicationModule == null) { | ||
return; | ||
} | ||
if (!(servlet instanceof HttpServlet)) { | ||
return; | ||
} | ||
final ServletContext context = ((HttpServlet) servlet).getServletContext(); | ||
if (InstrumentationContext.get(ServletContext.class, Boolean.class).get(context) != null) { | ||
return; | ||
} | ||
InstrumentationContext.get(ServletContext.class, Boolean.class).put(context, true); | ||
if (applicationModule != null) { | ||
applicationModule.onRealPath(context.getRealPath("/")); | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
...t-2/src/main/java/datadog/trace/instrumentation/servlet2/IastServlet2Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package datadog.trace.instrumentation.servlet2; | ||
|
||
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamed; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; | ||
import static net.bytebuddy.matcher.ElementMatchers.isPublic; | ||
import static net.bytebuddy.matcher.ElementMatchers.not; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
import com.google.auto.service.AutoService; | ||
import datadog.trace.agent.tooling.Instrumenter; | ||
import datadog.trace.agent.tooling.InstrumenterModule; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
@AutoService(InstrumenterModule.class) | ||
public final class IastServlet2Instrumentation extends InstrumenterModule.Iast | ||
implements Instrumenter.ForTypeHierarchy { | ||
|
||
public IastServlet2Instrumentation() { | ||
super("servlet", "servlet-2"); | ||
} | ||
|
||
@Override | ||
public String muzzleDirective() { | ||
return "servlet-2.x"; | ||
} | ||
|
||
// Avoid matching servlet 3 which has its own instrumentation | ||
static final ElementMatcher<ClassLoader> NOT_SERVLET_3 = | ||
not(hasClassNamed("javax.servlet.AsyncEvent")); | ||
|
||
@Override | ||
public ElementMatcher<ClassLoader> classLoaderMatcher() { | ||
return NOT_SERVLET_3; | ||
} | ||
|
||
@Override | ||
public String hierarchyMarkerType() { | ||
return "javax.servlet.http.HttpServlet"; | ||
} | ||
|
||
@Override | ||
public ElementMatcher<TypeDescription> hierarchyMatcher() { | ||
return extendsClass(named("javax.servlet.http.HttpServlet")) | ||
.or(implementsInterface(named("javax.servlet.FilterChain"))); | ||
} | ||
|
||
@Override | ||
public Map<String, String> contextStore() { | ||
return Collections.singletonMap("javax.servlet.ServletContext", Boolean.class.getName()); | ||
} | ||
|
||
@Override | ||
public void methodAdvice(MethodTransformer transformer) { | ||
transformer.applyAdvice( | ||
namedOneOf("doFilter", "service") | ||
.and(takesArgument(0, named("javax.servlet.ServletRequest"))) | ||
.and(takesArgument(1, named("javax.servlet.ServletResponse"))) | ||
.and(isPublic()), | ||
packageName + ".IastServlet2Advice"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...et/request-3/src/main/java/datadog/trace/instrumentation/servlet3/IastServlet3Advice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package datadog.trace.instrumentation.servlet3; | ||
|
||
import datadog.trace.api.iast.InstrumentationBridge; | ||
import datadog.trace.api.iast.Sink; | ||
import datadog.trace.api.iast.VulnerabilityTypes; | ||
import datadog.trace.api.iast.sink.ApplicationModule; | ||
import datadog.trace.bootstrap.InstrumentationContext; | ||
import javax.servlet.ServletContext; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.http.HttpServletRequest; | ||
import net.bytebuddy.asm.Advice; | ||
|
||
public class IastServlet3Advice { | ||
|
||
@Sink(VulnerabilityTypes.APPLICATION) | ||
@Advice.OnMethodExit(suppress = Throwable.class) | ||
public static void onExit(@Advice.Argument(0) ServletRequest request) { | ||
final ApplicationModule applicationModule = InstrumentationBridge.APPLICATION; | ||
if (applicationModule == null) { | ||
return; | ||
} | ||
if (!(request instanceof HttpServletRequest)) { | ||
return; | ||
} | ||
final ServletContext context = request.getServletContext(); | ||
if (InstrumentationContext.get(ServletContext.class, Boolean.class).get(context) != null) { | ||
return; | ||
} | ||
InstrumentationContext.get(ServletContext.class, Boolean.class).put(context, true); | ||
applicationModule.onRealPath(context.getRealPath("/")); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
...t-3/src/main/java/datadog/trace/instrumentation/servlet3/IastServlet3Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package datadog.trace.instrumentation.servlet3; | ||
|
||
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamed; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; | ||
import static net.bytebuddy.matcher.ElementMatchers.isPublic; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
import com.google.auto.service.AutoService; | ||
import datadog.trace.agent.tooling.Instrumenter; | ||
import datadog.trace.agent.tooling.InstrumenterModule; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
@AutoService(InstrumenterModule.class) | ||
public final class IastServlet3Instrumentation extends InstrumenterModule.Iast | ||
implements Instrumenter.ForTypeHierarchy { | ||
public IastServlet3Instrumentation() { | ||
super("servlet", "servlet-3"); | ||
} | ||
|
||
@Override | ||
public String muzzleDirective() { | ||
return "servlet-3.x"; | ||
} | ||
|
||
@Override | ||
public ElementMatcher<ClassLoader> classLoaderMatcher() { | ||
// Avoid matching servlet 2 which has its own instrumentation | ||
return hasClassNamed("javax.servlet.AsyncEvent"); | ||
} | ||
|
||
@Override | ||
public String hierarchyMarkerType() { | ||
return "javax.servlet.http.HttpServlet"; | ||
} | ||
|
||
@Override | ||
public ElementMatcher<TypeDescription> hierarchyMatcher() { | ||
return extendsClass(named("javax.servlet.http.HttpServlet")) | ||
.or(implementsInterface(named("javax.servlet.FilterChain"))); | ||
} | ||
|
||
@Override | ||
public Map<String, String> contextStore() { | ||
return Collections.singletonMap("javax.servlet.ServletContext", Boolean.class.getName()); | ||
} | ||
|
||
@Override | ||
public void methodAdvice(MethodTransformer transformer) { | ||
transformer.applyAdvice( | ||
namedOneOf("doFilter", "service") | ||
.and(takesArgument(0, named("javax.servlet.ServletRequest"))) | ||
.and(takesArgument(1, named("javax.servlet.ServletResponse"))) | ||
.and(isPublic()), | ||
packageName + ".IastServlet3Advice"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.