mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Promote exxperimental XXE sinks
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/** Provides XML definitions related to the `org.apache.commons` package. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.RangeUtils
|
||||
private import semmle.code.java.security.XmlParsers
|
||||
|
||||
/**
|
||||
* The classes `org.apache.commons.digester3.Digester`, `org.apache.commons.digester.Digester` or `org.apache.tomcat.util.digester.Digester`.
|
||||
*/
|
||||
private class Digester extends RefType {
|
||||
Digester() {
|
||||
this.hasQualifiedName([
|
||||
"org.apache.commons.digester3", "org.apache.commons.digester",
|
||||
"org.apache.tomcat.util.digester"
|
||||
], "Digester")
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `Digester.parse`. */
|
||||
private class DigesterParse extends XmlParserCall {
|
||||
DigesterParse() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof Digester and
|
||||
m.hasName("parse")
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getSink() { result = this.getArgument(0) }
|
||||
|
||||
override predicate isSafe() { SafeDigesterFlow::flowToExpr(this.getQualifier()) }
|
||||
}
|
||||
|
||||
/** A `ParserConfig` that is specific to `Digester`. */
|
||||
private class DigesterConfig extends ParserConfig {
|
||||
DigesterConfig() {
|
||||
exists(Method m |
|
||||
m = this.getMethod() and
|
||||
m.getDeclaringType() instanceof Digester and
|
||||
m.hasName("setFeature")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A safely configured `Digester`.
|
||||
*/
|
||||
private class SafeDigester extends VarAccess {
|
||||
SafeDigester() {
|
||||
exists(Variable v | v = this.getVariable() |
|
||||
exists(DigesterConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config.enables(singleSafeConfig())
|
||||
)
|
||||
or
|
||||
exists(DigesterConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config
|
||||
.disables(any(ConstantStringExpr s |
|
||||
s.getStringValue() = "http://xml.org/sax/features/external-general-entities"
|
||||
))
|
||||
) and
|
||||
exists(DigesterConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config
|
||||
.disables(any(ConstantStringExpr s |
|
||||
s.getStringValue() = "http://xml.org/sax/features/external-parameter-entities"
|
||||
))
|
||||
) and
|
||||
exists(DigesterConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config
|
||||
.disables(any(ConstantStringExpr s |
|
||||
s.getStringValue() =
|
||||
"http://apache.org/xml/features/nonvalidating/load-external-dtd"
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module SafeDigesterFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDigester }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodAccess ma |
|
||||
sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof Digester
|
||||
)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
private module SafeDigesterFlow = DataFlow::Global<SafeDigesterFlowConfig>;
|
||||
64
java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll
Normal file
64
java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll
Normal file
@@ -0,0 +1,64 @@
|
||||
/** Provides definitions related to the `javax.xml` package. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.security.XmlParsers
|
||||
|
||||
/** A call to `Validator.validate`. */
|
||||
private class ValidatorValidate extends XmlParserCall {
|
||||
ValidatorValidate() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof Validator and
|
||||
m.hasName("validate")
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getSink() { result = this.getArgument(0) }
|
||||
|
||||
override predicate isSafe() { SafeValidatorFlow::flowToExpr(this.getQualifier()) }
|
||||
}
|
||||
|
||||
/** A `TransformerConfig` specific to `Validator`. */
|
||||
private class ValidatorConfig extends TransformerConfig {
|
||||
ValidatorConfig() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof Validator and
|
||||
m.hasName("setProperty")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The class `javax.xml.validation.Validator`. */
|
||||
private class Validator extends RefType {
|
||||
Validator() { this.hasQualifiedName("javax.xml.validation", "Validator") }
|
||||
}
|
||||
|
||||
/** A safely configured `Validator`. */
|
||||
private class SafeValidator extends VarAccess {
|
||||
SafeValidator() {
|
||||
exists(Variable v | v = this.getVariable() |
|
||||
exists(ValidatorConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config.disables(configAccessExternalDtd())
|
||||
) and
|
||||
exists(ValidatorConfig config | config.getQualifier() = v.getAnAccess() |
|
||||
config.disables(configAccessExternalSchema())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module SafeValidatorFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeValidator }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodAccess ma |
|
||||
sink.asExpr() = ma.getQualifier() and
|
||||
ma.getMethod().getDeclaringType() instanceof Validator
|
||||
)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
private module SafeValidatorFlow = DataFlow::Global<SafeValidatorFlowConfig>;
|
||||
24
java/ql/lib/semmle/code/java/frameworks/javase/Beans.qll
Normal file
24
java/ql/lib/semmle/code/java/frameworks/javase/Beans.qll
Normal file
@@ -0,0 +1,24 @@
|
||||
/** Provides definitions related to the `java.beans` package. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.security.XmlParsers
|
||||
|
||||
/** The class `java.beans.XMLDecoder`. */
|
||||
private class XmlDecoder extends RefType {
|
||||
XmlDecoder() { this.hasQualifiedName("java.beans", "XMLDecoder") }
|
||||
}
|
||||
|
||||
/** A call to `XMLDecoder.readObject`. */
|
||||
private class XmlDecoderReadObject extends XmlParserCall {
|
||||
XmlDecoderReadObject() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof XmlDecoder and
|
||||
m.hasName("readObject")
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getSink() { result = this.getQualifier() }
|
||||
|
||||
override predicate isSafe() { none() }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/** Provides definitions related to XML parsing in Rundeck. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.security.XmlParsers
|
||||
|
||||
/** A call to `ParserHelper.loadDocument`. */
|
||||
private class ParserHelperLoadDocument extends XmlParserCall {
|
||||
ParserHelperLoadDocument() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType().hasQualifiedName("org.rundeck.api.parser", "ParserHelper") and
|
||||
m.hasName("loadDocument")
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getSink() { result = this.getArgument(0) }
|
||||
|
||||
override predicate isSafe() { none() }
|
||||
}
|
||||
@@ -2,13 +2,15 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.DataFlow2
|
||||
import semmle.code.java.dataflow.DataFlow3
|
||||
private import semmle.code.java.dataflow.RangeUtils
|
||||
|
||||
/*
|
||||
* Various XML parsers in Java.
|
||||
*/
|
||||
private module Frameworks {
|
||||
private import semmle.code.java.frameworks.apache.CommonsXml
|
||||
private import semmle.code.java.frameworks.javaee.Xml
|
||||
private import semmle.code.java.frameworks.javase.Beans
|
||||
private import semmle.code.java.frameworks.rundeck.RundeckXml
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract type representing a call to parse XML files.
|
||||
@@ -946,7 +948,7 @@ class TransformerFactorySource extends XmlParserCall {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof TransformerFactory and
|
||||
m.hasName("newTransformer")
|
||||
m.hasName(["newTransformer", "newTransformerHandler"])
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user