diff --git a/java/ql/src/experimental/Security/CWE/CWE-489/StrutsBad.xml b/java/ql/src/experimental/Security/CWE/CWE-489/StrutsBad.xml new file mode 100644 index 00000000000..64e614cc525 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-489/StrutsBad.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/java/ql/src/experimental/Security/CWE/CWE-489/StrutsGood.xml b/java/ql/src/experimental/Security/CWE/CWE-489/StrutsGood.xml new file mode 100644 index 00000000000..369b42a7ec9 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-489/StrutsGood.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-489/devMode.qhelp b/java/ql/src/experimental/Security/CWE/CWE-489/devMode.qhelp new file mode 100644 index 00000000000..4775bd8e0e2 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-489/devMode.qhelp @@ -0,0 +1,32 @@ + + + + +

Turning Apache Struts' development mode configuration on while deploying applications to production environments can lead to remote code execution.

+ +
+ + +

An application should disable the development mode at the time of deployment.

+ +
+ + +

The following example shows a `struts.xml` file with `struts.devmode` enabled.

+ + + +

This can be easily corrected by setting the value of the `struts.devmode` parameter to false.

+ + + +
+ + +
  • + Apache Struts: + Struts development mode configuration +
  • + +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-489/devMode.ql b/java/ql/src/experimental/Security/CWE/CWE-489/devMode.ql new file mode 100644 index 00000000000..1bbb1b71ab4 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-489/devMode.ql @@ -0,0 +1,24 @@ +/** + * @name Apache Struts development mode enabled + * @description Enabling struts development mode in production environment + * can lead to remote code execution. + * @kind problem + * @problem.severity error + * @precision high + * @id java/struts-development-mode + * @tags security + * external/cwe/cwe-489 + */ + +import java +import experimental.semmle.code.xml.StrutsXML + +bindingset[path] +predicate isLikelyDemoProject(string path) { path.regexpMatch("(?i).*(demo|test|example).*") } + +from ConstantParameter c +where + c.getNameValue() = "struts.devMode" and + c.getValueValue() = "true" and + not isLikelyDemoProject(c.getFile().getRelativePath()) +select c, "Enabling development mode in production environments is dangerous" diff --git a/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll new file mode 100644 index 00000000000..06e1dab79af --- /dev/null +++ b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll @@ -0,0 +1,40 @@ +import java + +/** + * A deployment descriptor file, typically called `struts.xml`. + */ +class StrutsXMLFile extends XMLFile { + StrutsXMLFile() { + count(XMLElement e | e = this.getAChild()) = 1 and + this.getAChild().getName() = "struts" + } +} + +/** + * An XML element in a `StrutsXMLFile`. + */ +class StrutsXMLElement extends XMLElement { + StrutsXMLElement() { this.getFile() instanceof StrutsXMLFile } + + /** + * Gets the value for this element, with leading and trailing whitespace trimmed. + */ + string getValue() { result = allCharactersString().trim() } +} + +/** + * A `` element in a `StrutsXMLFile`. + */ +class ConstantParameter extends StrutsXMLElement { + ConstantParameter() { this.getName() = "constant" } + + /** + * Gets the value of the `name` attribute of this ``. + */ + string getNameValue() { result = getAttributeValue("name") } + + /** + * Gets the value of the `value` attribute of this ``. + */ + string getValueValue() { result = getAttributeValue("value") } +}