Skip to content

Commit 652193c

Browse files
authored
Add directory listing WEBLOGIC, WEBSPHERE and JETTY support (#6871)
Report Directory listing leak when: <param-name>dirAllowed</param-name> is present in web.xml file (Jetty Servers) <index-directory-enabled>true</index-directory-enabled> is present in weblogic.xml (WebLogic Servers) directoryBrowsingEnabled="true" is present in ibm-web-ext.xmi (WebSphere Servers) <enable-directory-browsing value="true"/> is present in ibm-web-ext.xml (WebSphere Servers)
1 parent 91854ff commit 652193c

File tree

7 files changed

+137
-10
lines changed

7 files changed

+137
-10
lines changed

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/sink/ApplicationModuleImpl.java

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application
4848
"org.springframework.web.servlet.DispatcherServlet";
4949
private static final String DEFAULT_HTML_ESCAPE = "defaultHtmlEscape";
5050
private static final String LISTINGS_PATTERN = "<param-name>listings</param-name>";
51+
private static final String JETTY_LISTINGS_PATTERN = "<param-name>dirAllowed</param-name>";
52+
private static final String WEBLOGIC_LISTING_PATTERN =
53+
"<index-directory-enabled>true</index-directory-enabled>";
54+
private static final String WEBSPHERE_XMI_LISTING_PATTERN = "directoryBrowsingEnabled=\"true\"";
55+
private static final String WEBSPHERE_XML_LISTING_PATTERN =
56+
"<enable-directory-browsing value=\"true\"/>";
5157
private static final String SESSION_TIMEOUT_START_TAG = "<session-timeout>";
5258
private static final String SESSION_TIMEOUT_END_TAG = "</session-timeout>";
5359
private static final String SECURITY_CONSTRAINT_START_TAG = "<security-constraint>";
@@ -64,6 +70,9 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application
6470
DISPLAY_NAME_START_TAG + TOMCAT_HOST_MANAGER_APP + DISPLAY_NAME_END_TAG;
6571
public static final String WEB_INF = "WEB-INF";
6672
public static final String WEB_XML = "web.xml";
73+
public static final String WEBLOGIC_XML = "weblogic.xml";
74+
public static final String IBM_WEB_EXT_XMI = "ibm-web-ext.xmi";
75+
public static final String IBM_WEB_EXT_XML = "ibm-web-ext.xml";
6776
static final String SESSION_REWRITING_EVIDENCE_VALUE = "Servlet URL Session Tracking Mode";
6877

6978
private static final Pattern PATTERN =
@@ -75,11 +84,21 @@ public class ApplicationModuleImpl extends SinkModuleBase implements Application
7584
TOMCAT_MANAGER_APP_PATTERN,
7685
TOMCAT_HOST_MANAGER_APP_PATTERN,
7786
LISTINGS_PATTERN,
87+
JETTY_LISTINGS_PATTERN,
7888
SESSION_TIMEOUT_START_TAG,
7989
SECURITY_CONSTRAINT_START_TAG)
8090
.map(Pattern::quote)
8191
.collect(Collectors.joining("|")));
8292

93+
private static final Pattern WEBLOGIC_PATTERN =
94+
Pattern.compile(WEBLOGIC_LISTING_PATTERN, Pattern.CASE_INSENSITIVE);
95+
96+
private static final Pattern WEBSPHERE_XMI_PATTERN =
97+
Pattern.compile(WEBSPHERE_XMI_LISTING_PATTERN, Pattern.CASE_INSENSITIVE);
98+
99+
private static final Pattern WEBSPHERE_XML_PATTERN =
100+
Pattern.compile(WEBSPHERE_XML_LISTING_PATTERN, Pattern.CASE_INSENSITIVE);
101+
83102
private static final int NO_LINE = -1;
84103

85104
public ApplicationModuleImpl(final Dependencies dependencies) {
@@ -103,6 +122,10 @@ public void onRealPath(final @Nullable String realPath) {
103122
final AgentSpan span = AgentTracer.activeSpan();
104123
checkInsecureJSPLayout(root, span);
105124
checkWebXmlVulnerabilities(root, span);
125+
// WEBLOGIC
126+
checkWeblogicVulnerabilities(root, span);
127+
// WEBSPHERE
128+
checkWebsphereVulnerabilities(root, span);
106129
}
107130

108131
/**
@@ -125,8 +148,46 @@ public void checkSessionTrackingModes(@Nonnull Set<String> sessionTrackingModes)
125148
new Evidence(SESSION_REWRITING_EVIDENCE_VALUE)));
126149
}
127150

128-
private void checkWebXmlVulnerabilities(@Nonnull Path path, AgentSpan span) {
129-
String webXmlContent = webXmlContent(path);
151+
private void checkWebsphereVulnerabilities(@Nonnull final Path path, final AgentSpan span) {
152+
checkWebsphereXMLVulnerabilities(path, span);
153+
checkWebsphereXMIVulnerabilities(path, span);
154+
}
155+
156+
private void checkWebsphereXMIVulnerabilities(@Nonnull final Path path, final AgentSpan span) {
157+
String xmlContent = getXmlContent(path, IBM_WEB_EXT_XMI);
158+
if (xmlContent == null) {
159+
return;
160+
}
161+
Matcher matcher = WEBSPHERE_XMI_PATTERN.matcher(xmlContent);
162+
while (matcher.find()) {
163+
reportDirectoryListingLeak(xmlContent, matcher.start(), span);
164+
}
165+
}
166+
167+
private void checkWebsphereXMLVulnerabilities(@Nonnull final Path path, final AgentSpan span) {
168+
String xmlContent = getXmlContent(path, IBM_WEB_EXT_XML);
169+
if (xmlContent == null) {
170+
return;
171+
}
172+
Matcher matcher = WEBSPHERE_XML_PATTERN.matcher(xmlContent);
173+
while (matcher.find()) {
174+
reportDirectoryListingLeak(xmlContent, matcher.start(), span);
175+
}
176+
}
177+
178+
private void checkWeblogicVulnerabilities(@Nonnull final Path path, final AgentSpan span) {
179+
String xmlContent = getXmlContent(path, WEBLOGIC_XML);
180+
if (xmlContent == null) {
181+
return;
182+
}
183+
Matcher matcher = WEBLOGIC_PATTERN.matcher(xmlContent);
184+
while (matcher.find()) {
185+
reportDirectoryListingLeak(xmlContent, matcher.start(), span);
186+
}
187+
}
188+
189+
private void checkWebXmlVulnerabilities(@Nonnull final Path path, final AgentSpan span) {
190+
String webXmlContent = getXmlContent(path, WEB_XML);
130191
if (webXmlContent == null) {
131192
return;
132193
}
@@ -152,6 +213,7 @@ private void checkWebXmlVulnerabilities(@Nonnull Path path, AgentSpan span) {
152213
reportAdminConsoleActive(span, TOMCAT_HOST_MANAGER_APP);
153214
break;
154215
case LISTINGS_PATTERN:
216+
case JETTY_LISTINGS_PATTERN:
155217
checkDirectoryListingLeak(webXmlContent, matcher.start(), span);
156218
break;
157219
case SESSION_TIMEOUT_START_TAG:
@@ -211,14 +273,19 @@ private void checkDirectoryListingLeak(
211273
int valueLast = webXmlContent.indexOf(PARAM_VALUE_END_TAG, valueIndex);
212274
String data = substringTrim(webXmlContent, valueIndex, valueLast);
213275
if (data.equalsIgnoreCase("true")) {
214-
report(
215-
span,
216-
VulnerabilityType.DIRECTORY_LISTING_LEAK,
217-
"Directory listings configured",
218-
getLine(webXmlContent, index));
276+
reportDirectoryListingLeak(webXmlContent, index, span);
219277
}
220278
}
221279

280+
private void reportDirectoryListingLeak(
281+
final String webXmlContent, int index, final AgentSpan span) {
282+
report(
283+
span,
284+
VulnerabilityType.DIRECTORY_LISTING_LEAK,
285+
"Directory listings configured",
286+
getLine(webXmlContent, index));
287+
}
288+
222289
private void checkSessionTimeOut(final String webXmlContent, int index, final AgentSpan span) {
223290
try {
224291
String innerText =
@@ -288,8 +355,8 @@ private static int getLine(String webXmlContent, int index) {
288355
}
289356

290357
@Nullable
291-
private static String webXmlContent(final Path realPath) {
292-
Path path = realPath.resolve(WEB_INF).resolve(WEB_XML);
358+
private static String getXmlContent(final Path realPath, final String fileName) {
359+
Path path = realPath.resolve(WEB_INF).resolve(fileName);
293360
if (Files.exists(path)) {
294361
try {
295362
return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ class ApplicationModuleTest extends IastModuleImplTestBase {
6464
'application/sessiontimeout/secure' | null | null | _
6565
'application/sessiontimeout/insecure' | SESSION_TIMEOUT | 'Found vulnerable timeout value: 80' | 7
6666
'application/directorylistingleak/secure' | null | null | _
67-
'application/directorylistingleak/insecure' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 14
67+
'application/directorylistingleak/insecure/tomcat'| DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 14
68+
'application/directorylistingleak/insecure/weblogic' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 17
69+
'application/directorylistingleak/insecure/websphere/xmi' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 1
70+
'application/directorylistingleak/insecure/websphere/xml' | DIRECTORY_LISTING_LEAK | 'Directory listings configured' | 10
6871
'application/adminconsoleactive/secure' | null | null | _
6972
'application/adminconsoleactive/insecure/tomcat/manager' | ADMIN_CONSOLE_ACTIVE | ApplicationModuleImpl.TOMCAT_MANAGER_APP | NO_LINE
7073
'application/adminconsoleactive/insecure/tomcat/host' | ADMIN_CONSOLE_ACTIVE | ApplicationModuleImpl.TOMCAT_HOST_MANAGER_APP | NO_LINE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://java.sun.com/xml/ns/javaee"
4+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
5+
id="WebApp_ID" version="3.0">
6+
<servlet>
7+
<servlet-name>default</servlet-name>
8+
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
9+
<init-param>
10+
<param-name>resourceBase</param-name>
11+
<param-value>/path/to/your/static/files</param-value>
12+
</init-param>
13+
<init-param>
14+
<param-name>dirAllowed</param-name>
15+
<param-value>true</param-value>
16+
</init-param>
17+
</servlet>
18+
<servlet-mapping>
19+
<servlet-name>default</servlet-name>
20+
<url-pattern>/*</url-pattern>
21+
</servlet-mapping>
22+
</web-app>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
3+
<container-descriptor>
4+
<prefer-web-inf-classes>false</prefer-web-inf-classes>
5+
<prefer-application-packages>
6+
<package-name>javax.faces.*</package-name>
7+
<package-name>com.sun.faces.*</package-name>
8+
<package-name>com.bea.faces.*</package-name>
9+
</prefer-application-packages>
10+
11+
<prefer-application-resources>
12+
<resource-name>javax.faces.*</resource-name>
13+
<resource-name>com.sun.faces.*</resource-name>
14+
<resource-name>com.bea.faces.*</resource-name>
15+
<resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
16+
</prefer-application-resources>
17+
<index-directory-enabled>true</index-directory-enabled>
18+
</container-descriptor>
19+
</weblogic-web-app>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
directoryBrowsingEnabled="true"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<web-ext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://websphere.ibm.com/xml/ns/javaee"
3+
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd" version="1.0">
4+
<jsp-attribute name="reloadEnabled" value="true"/>
5+
<jsp-attribute name="reloadInterval" value="10"/>
6+
7+
<reload-interval value="3"/>
8+
<enable-reloading value="true"/>
9+
<enable-file-serving value="false"/>
10+
<enable-directory-browsing value="true"/>
11+
<enable-serving-servlets-by-class-name value="true" />
12+
<pre-compile-jsps value="false"/>
13+
<auto-encode-requests value="false"/>
14+
<auto-encode-responses value="false"/>
15+
</web-ext>

0 commit comments

Comments
 (0)