From 231e9778e22ff1e09b3cc215ade2b90c357b816f Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Wed, 3 Apr 2024 10:48:40 +0200 Subject: [PATCH] Add directory listing WEBLOGIC, WEBSPHERE and JETTY support --- .../iast/sink/ApplicationModuleImpl.java | 85 +++++++++++++++++-- .../iast/sink/ApplicationModuleTest.groovy | 5 +- .../insecure/jetty/WEB-INF/web.xml | 22 +++++ .../insecure/{ => tomcat}/WEB-INF/web.xml | 0 .../insecure/weblogic/WEB-INF/weblogic.xml | 19 +++++ .../websphere/xmi/WEB-INF/ibm-web-ext.xmi | 1 + .../websphere/xml/WEB-INF/ibm-web-ext.xml | 15 ++++ 7 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/jetty/WEB-INF/web.xml rename dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/{ => tomcat}/WEB-INF/web.xml (100%) create mode 100644 dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/weblogic/WEB-INF/weblogic.xml create mode 100644 dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xmi/WEB-INF/ibm-web-ext.xmi create mode 100644 dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xml/WEB-INF/ibm-web-ext.xml diff --git a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/ApplicationModuleImpl.java b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/ApplicationModuleImpl.java index 7ad1f0c354e..d9e34ee4b1a 100644 --- a/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/ApplicationModuleImpl.java +++ b/dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/ApplicationModuleImpl.java @@ -48,6 +48,12 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application "org.springframework.web.servlet.DispatcherServlet"; private static final String DEFAULT_HTML_ESCAPE = "defaultHtmlEscape"; private static final String LISTINGS_PATTERN = "listings"; + private static final String JETTY_LISTINGS_PATTERN = "dirAllowed"; + private static final String WEBLOGIC_LISTING_PATTERN = + "true"; + private static final String WEBSPHERE_XMI_LISTING_PATTERN = "directoryBrowsingEnabled=\"true\""; + private static final String WEBSPHERE_XML_LISTING_PATTERN = + ""; private static final String SESSION_TIMEOUT_START_TAG = ""; private static final String SESSION_TIMEOUT_END_TAG = ""; private static final String SECURITY_CONSTRAINT_START_TAG = ""; @@ -64,6 +70,9 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application DISPLAY_NAME_START_TAG + TOMCAT_HOST_MANAGER_APP + DISPLAY_NAME_END_TAG; public static final String WEB_INF = "WEB-INF"; public static final String WEB_XML = "web.xml"; + public static final String WEBLOGIC_XML = "weblogic.xml"; + public static final String IBM_WEB_EXT_XMI = "ibm-web-ext.xmi"; + public static final String IBM_WEB_EXT_XML = "ibm-web-ext.xml"; static final String SESSION_REWRITING_EVIDENCE_VALUE = "Servlet URL Session Tracking Mode"; private static final Pattern PATTERN = @@ -75,11 +84,21 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application TOMCAT_MANAGER_APP_PATTERN, TOMCAT_HOST_MANAGER_APP_PATTERN, LISTINGS_PATTERN, + JETTY_LISTINGS_PATTERN, SESSION_TIMEOUT_START_TAG, SECURITY_CONSTRAINT_START_TAG) .map(Pattern::quote) .collect(Collectors.joining("|"))); + private static final Pattern WEBLOGIC_PATTERN = + Pattern.compile(WEBLOGIC_LISTING_PATTERN, Pattern.CASE_INSENSITIVE); + + private static final Pattern WEBSPHERE_XMI_PATTERN = + Pattern.compile(WEBSPHERE_XMI_LISTING_PATTERN, Pattern.CASE_INSENSITIVE); + + private static final Pattern WEBSPHERE_XML_PATTERN = + Pattern.compile(WEBSPHERE_XML_LISTING_PATTERN, Pattern.CASE_INSENSITIVE); + private static final int NO_LINE = -1; public ApplicationModuleImpl(final Dependencies dependencies) { @@ -103,6 +122,10 @@ public void onRealPath(final @Nullable String realPath) { final AgentSpan span = AgentTracer.activeSpan(); checkInsecureJSPLayout(root, span); checkWebXmlVulnerabilities(root, span); + // WEBLOGIC + checkWeblogicVulnerabilities(root, span); + // WEBSPHERE + checkWebsphereVulnerabilities(root, span); } /** @@ -125,8 +148,46 @@ public void checkSessionTrackingModes(@Nonnull Set sessionTrackingModes) new Evidence(SESSION_REWRITING_EVIDENCE_VALUE))); } - private void checkWebXmlVulnerabilities(@Nonnull Path path, AgentSpan span) { - String webXmlContent = webXmlContent(path); + private void checkWebsphereVulnerabilities(@Nonnull final Path path, final AgentSpan span) { + checkWebsphereXMLVulnerabilities(path, span); + checkWebsphereXMIVulnerabilities(path, span); + } + + private void checkWebsphereXMIVulnerabilities(@Nonnull final Path path, final AgentSpan span) { + String xmlContent = getXmlContent(path, IBM_WEB_EXT_XMI); + if (xmlContent == null) { + return; + } + Matcher matcher = WEBSPHERE_XMI_PATTERN.matcher(xmlContent); + while (matcher.find()) { + reportDirectoryListingLeak(xmlContent, matcher.start(), span); + } + } + + private void checkWebsphereXMLVulnerabilities(@Nonnull final Path path, final AgentSpan span) { + String xmlContent = getXmlContent(path, IBM_WEB_EXT_XML); + if (xmlContent == null) { + return; + } + Matcher matcher = WEBSPHERE_XML_PATTERN.matcher(xmlContent); + while (matcher.find()) { + reportDirectoryListingLeak(xmlContent, matcher.start(), span); + } + } + + private void checkWeblogicVulnerabilities(@Nonnull final Path path, final AgentSpan span) { + String xmlContent = getXmlContent(path, WEBLOGIC_XML); + if (xmlContent == null) { + return; + } + Matcher matcher = WEBLOGIC_PATTERN.matcher(xmlContent); + while (matcher.find()) { + reportDirectoryListingLeak(xmlContent, matcher.start(), span); + } + } + + private void checkWebXmlVulnerabilities(@Nonnull final Path path, final AgentSpan span) { + String webXmlContent = getXmlContent(path, WEB_XML); if (webXmlContent == null) { return; } @@ -152,6 +213,7 @@ private void checkWebXmlVulnerabilities(@Nonnull Path path, AgentSpan span) { reportAdminConsoleActive(span, TOMCAT_HOST_MANAGER_APP); break; case LISTINGS_PATTERN: + case JETTY_LISTINGS_PATTERN: checkDirectoryListingLeak(webXmlContent, matcher.start(), span); break; case SESSION_TIMEOUT_START_TAG: @@ -211,14 +273,19 @@ private void checkDirectoryListingLeak( int valueLast = webXmlContent.indexOf(PARAM_VALUE_END_TAG, valueIndex); String data = substringTrim(webXmlContent, valueIndex, valueLast); if (data.equalsIgnoreCase("true")) { - report( - span, - VulnerabilityType.DIRECTORY_LISTING_LEAK, - "Directory listings configured", - getLine(webXmlContent, index)); + reportDirectoryListingLeak(webXmlContent, index, span); } } + private void reportDirectoryListingLeak( + final String webXmlContent, int index, final AgentSpan span) { + report( + span, + VulnerabilityType.DIRECTORY_LISTING_LEAK, + "Directory listings configured", + getLine(webXmlContent, index)); + } + private void checkSessionTimeOut(final String webXmlContent, int index, final AgentSpan span) { try { String innerText = @@ -288,8 +355,8 @@ private static int getLine(String webXmlContent, int index) { } @Nullable - private static String webXmlContent(final Path realPath) { - Path path = realPath.resolve(WEB_INF).resolve(WEB_XML); + private static String getXmlContent(final Path realPath, final String fileName) { + Path path = realPath.resolve(WEB_INF).resolve(fileName); if (Files.exists(path)) { try { return new String(Files.readAllBytes(path), StandardCharsets.UTF_8); diff --git a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/ApplicationModuleTest.groovy b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/ApplicationModuleTest.groovy index 37cc238ea4a..e2d0a9cb005 100644 --- a/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/ApplicationModuleTest.groovy +++ b/dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/sink/ApplicationModuleTest.groovy @@ -64,7 +64,10 @@ class ApplicationModuleTest extends IastModuleImplTestBase { 'application/sessiontimeout/secure' | null | null | _ 'application/sessiontimeout/insecure' | SESSION_TIMEOUT | 'Found vulnerable timeout value: 80' | 7 'application/directorylistingleak/secure' | null | null | _ - 'application/directorylistingleak/insecure' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 14 + 'application/directorylistingleak/insecure/tomcat'| DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 14 + 'application/directorylistingleak/insecure/weblogic' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 17 + 'application/directorylistingleak/insecure/websphere/xmi' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 1 + 'application/directorylistingleak/insecure/websphere/xml' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 10 'application/adminconsoleactive/secure' | null | null | _ 'application/adminconsoleactive/insecure/tomcat/manager' | ADMIN_CONSOLE_ACTIVE | ApplicationModuleImpl.TOMCAT_MANAGER_APP | NO_LINE 'application/adminconsoleactive/insecure/tomcat/host' | ADMIN_CONSOLE_ACTIVE | ApplicationModuleImpl.TOMCAT_HOST_MANAGER_APP | NO_LINE diff --git a/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/jetty/WEB-INF/web.xml b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/jetty/WEB-INF/web.xml new file mode 100644 index 00000000000..c628f44e7b1 --- /dev/null +++ b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/jetty/WEB-INF/web.xml @@ -0,0 +1,22 @@ + + + + default + org.eclipse.jetty.servlet.DefaultServlet + + resourceBase + /path/to/your/static/files + + + dirAllowed + true + + + + default + /* + + diff --git a/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/WEB-INF/web.xml b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/tomcat/WEB-INF/web.xml similarity index 100% rename from dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/WEB-INF/web.xml rename to dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/tomcat/WEB-INF/web.xml diff --git a/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/weblogic/WEB-INF/weblogic.xml b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/weblogic/WEB-INF/weblogic.xml new file mode 100644 index 00000000000..07c710c7c98 --- /dev/null +++ b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/weblogic/WEB-INF/weblogic.xml @@ -0,0 +1,19 @@ + + + + false + + javax.faces.* + com.sun.faces.* + com.bea.faces.* + + + + javax.faces.* + com.sun.faces.* + com.bea.faces.* + META-INF/services/javax.servlet.ServletContainerInitializer + + true + + diff --git a/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xmi/WEB-INF/ibm-web-ext.xmi b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xmi/WEB-INF/ibm-web-ext.xmi new file mode 100644 index 00000000000..d8d941a8204 --- /dev/null +++ b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xmi/WEB-INF/ibm-web-ext.xmi @@ -0,0 +1 @@ +directoryBrowsingEnabled="true" diff --git a/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xml/WEB-INF/ibm-web-ext.xml b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xml/WEB-INF/ibm-web-ext.xml new file mode 100644 index 00000000000..a1e1b28fca3 --- /dev/null +++ b/dd-java-agent/agent-iast/src/test/resources/application/directorylistingleak/insecure/websphere/xml/WEB-INF/ibm-web-ext.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + +