Skip to content

Commit 0eb2c06

Browse files
authored
Merge pull request github#3945 from porcupineyhairs/structsDevMode
Java: Add query to detect Apache Struts enabled Devmode
2 parents 79839d2 + beb15e2 commit 0eb2c06

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!DOCTYPE struts PUBLIC
3+
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
4+
"http://struts.apache.org/dtds/struts-2.3.dtd">
5+
6+
<struts>
7+
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
8+
<constant name="struts.devMode" value="true" />
9+
<constant name="struts.i18n.encoding" value="utf-8" />
10+
<include file="login.xml" />
11+
</struts>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!DOCTYPE struts PUBLIC
3+
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
4+
"http://struts.apache.org/dtds/struts-2.3.dtd">
5+
6+
<struts>
7+
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
8+
<constant name="struts.devMode" value="false" />
9+
<constant name="struts.i18n.encoding" value="utf-8"></constant>
10+
<include file="login.xml" />
11+
</struts>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>Turning Apache Struts' development mode configuration on while deploying applications to production environments can lead to remote code execution.</p>
6+
7+
</overview>
8+
<recommendation>
9+
10+
<p>An application should disable the development mode at the time of deployment.</p>
11+
12+
</recommendation>
13+
<example>
14+
15+
<p>The following example shows a `struts.xml` file with `struts.devmode` enabled.</p>
16+
17+
<sample src="StrutsBad.xml" />
18+
19+
<p>This can be easily corrected by setting the value of the `struts.devmode` parameter to false.</p>
20+
21+
<sample src="StrutsGood.xml" />
22+
23+
</example>
24+
<references>
25+
26+
<li>
27+
Apache Struts:
28+
<a href="https://struts.apache.org/core-developers/development-mode.html">Struts development mode configuration</a>
29+
</li>
30+
31+
</references>
32+
</qhelp>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @name Apache Struts development mode enabled
3+
* @description Enabling struts development mode in production environment
4+
* can lead to remote code execution.
5+
* @kind problem
6+
* @problem.severity error
7+
* @precision high
8+
* @id java/struts-development-mode
9+
* @tags security
10+
* external/cwe/cwe-489
11+
*/
12+
13+
import java
14+
import experimental.semmle.code.xml.StrutsXML
15+
16+
bindingset[path]
17+
predicate isLikelyDemoProject(string path) { path.regexpMatch("(?i).*(demo|test|example).*") }
18+
19+
from ConstantParameter c
20+
where
21+
c.getNameValue() = "struts.devMode" and
22+
c.getValueValue() = "true" and
23+
not isLikelyDemoProject(c.getFile().getRelativePath())
24+
select c, "Enabling development mode in production environments is dangerous"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import java
2+
3+
/**
4+
* A deployment descriptor file, typically called `struts.xml`.
5+
*/
6+
class StrutsXMLFile extends XMLFile {
7+
StrutsXMLFile() {
8+
count(XMLElement e | e = this.getAChild()) = 1 and
9+
this.getAChild().getName() = "struts"
10+
}
11+
}
12+
13+
/**
14+
* An XML element in a `StrutsXMLFile`.
15+
*/
16+
class StrutsXMLElement extends XMLElement {
17+
StrutsXMLElement() { this.getFile() instanceof StrutsXMLFile }
18+
19+
/**
20+
* Gets the value for this element, with leading and trailing whitespace trimmed.
21+
*/
22+
string getValue() { result = allCharactersString().trim() }
23+
}
24+
25+
/**
26+
* A `<constant>` element in a `StrutsXMLFile`.
27+
*/
28+
class ConstantParameter extends StrutsXMLElement {
29+
ConstantParameter() { this.getName() = "constant" }
30+
31+
/**
32+
* Gets the value of the `name` attribute of this `<constant>`.
33+
*/
34+
string getNameValue() { result = getAttributeValue("name") }
35+
36+
/**
37+
* Gets the value of the `value` attribute of this `<constant>`.
38+
*/
39+
string getValueValue() { result = getAttributeValue("value") }
40+
}

0 commit comments

Comments
 (0)