C++: Get the simplest part of the query working, disable the rest for now, fix metadata, formatting etc.

This commit is contained in:
Geoffrey White
2022-04-07 18:56:21 +01:00
parent 9a0880f516
commit 3aaa058308
3 changed files with 146 additions and 42 deletions

View File

@@ -1,9 +1,11 @@
/**
* @name External Entity Expansion
* @description
* @description TODO
* @kind path-problem
* @id cpp/external-entity-expansion
* @problem.severity warning
* @security-severity TODO
* @precision TODO
* @tags security
* external/cwe/cwe-611
*/
@@ -13,52 +15,65 @@ import semmle.code.cpp.ir.dataflow.DataFlow
import DataFlow::PathGraph
import semmle.code.cpp.ir.IR
class XercesDOMParser extends Class {
XercesDOMParser() { this.hasName("XercesDOMParser") }
}
class AbstractDOMParser extends Class {
AbstractDOMParser() { this.hasName("AbstractDOMParser") }
}
class XercesDOMParser extends Class {
XercesDOMParser() { this.hasName("XercesDOMParser") }
}
class DisableDefaultEntityResolution extends Function {
DisableDefaultEntityResolution() {
this.hasQualifiedName(_, "AbstractOMParser", "setDisableDefaultEntityResolution")
this.getDeclaringType() instanceof AbstractDOMParser and
this.hasName("setDisableDefaultEntityResolution")
}
}
class SetCreateEntityReferenceNodes extends Function {
SetCreateEntityReferenceNodes() {
this.hasQualifiedName(_, "AbstractDOMParser", "setCreateEntityReferenceNodes")
this.getDeclaringType() instanceof AbstractDOMParser and
this.hasName("setCreateEntityReferenceNodes")
}
}
class CreateLSParser extends Function {
CreateLSParser() {
this.hasName("createLSParser")
class Parse extends Function {
Parse() {
this.getDeclaringType() instanceof AbstractDOMParser and
this.hasName("parse")
}
}
/*
class CreateLSParser extends Function {
CreateLSParser() { this.hasName("createLSParser") }
}
class SetSecurityManager extends Function {
SetSecurityManager() {
this.hasQualifiedName(_, "AbstractDOMParser", "setSecurityManager")
}
SetSecurityManager() { this.hasQualifiedName(_, "AbstractDOMParser", "setSecurityManager") }
}
class SAXParser extends Class {
SAXParser() { this.hasName("SAXParser") }
}
*/
class XercesXXEConfiguration extends DataFlow::Configuration {
XercesXXEConfiguration() { this = "XercesXXEConfiguration" }
override predicate isSource(DataFlow::Node node, string flowstate) {
override predicate isSource(DataFlow::Node node/*, string flowstate*/) {
// source is the write on `this` of a call to the XercesDOMParser
// constructor.
exists(CallInstruction call |
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() = call.getThisArgument() and
call.getStaticCallTarget().(Constructor).getDeclaringType() instanceof XercesDOMParser and
flowstate = "XercesDOM"
call.getStaticCallTarget() = any(XercesDOMParser c).getAConstructor() and
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
call.getThisArgument()/* and
flowstate = "XercesDOM"*/
)
or
/*exists(Call call |
call.getTarget() = any(XercesDOMParser c).getAConstructor() and
node.asExpr() = call
)*/
/* or
exists(Call call |
call.getTarget() instanceof CreateLSParser and
call = node.asExpr() and
@@ -66,21 +81,26 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
)
or
exists(CallInstruction call |
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() = call.getThisArgument() and
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
call.getThisArgument() and
call.getStaticCallTarget().(Constructor).getDeclaringType() instanceof SAXParser and
flowstate = "SAXParser"
)
)*/
}
override predicate isSink(DataFlow::Node node) {
exists(Call call, ReadSideEffectInstruction instr |
call.getTarget().hasName("parse") and
call.getQualifier() = instr.getArgumentDef().getUnconvertedResultExpression() and
node.asOperand() = instr.getSideEffectOperand()
// sink is the read of the qualifier of a call to `parse`.
exists(Call call/*, ReadSideEffectInstruction instr*/ |
call.getTarget() instanceof Parse and
call.getQualifier() = node.asConvertedExpr()
/*instr.getArgumentDef().getUnconvertedResultExpression() and
node.asOperand() = instr.getSideEffectOperand()*/
)
}
override predicate isAdditionalFlowStep(DataFlow::Node node1, string state1, DataFlow::Node node2, string state2) {
/*override predicate isAdditionalFlowStep(
DataFlow::Node node1, string state1, DataFlow::Node node2, string state2
) {
exists(Call call |
node1.asConvertedExpr() = call.getQualifier() and
node2.asDefiningArgument() = call.getQualifier() and
@@ -94,9 +114,9 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
state2 = "XercesDOM-SCERN"
)
)
}
}*/
override predicate isBarrier(DataFlow::Node node, string flowstate) {
/*override predicate isBarrier(DataFlow::Node node, string flowstate) {
exists(Call call |
(
flowstate = "XercesDOM-DDER" and
@@ -110,14 +130,15 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
or
exists(Call setSecurityManager |
// todo: security manager setup
flowstate = TODO
setSecurityManager.getQualifier() = node.asDefiningArgument() and
setSecurityManager.getTarget() instanceof SetSecurityManager
)
//or
}
}*/
}
/*
* TODO:
* parser created
* needs doSchema set?
* needs validation set?
@@ -128,7 +149,7 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
* no
*/
from DataFlow::PathNode source, DataFlow::PathNode sink, XercesXXEConfiguration conf
from XercesXXEConfiguration conf, DataFlow::PathNode source, DataFlow::PathNode sink
where conf.hasFlowPath(source, sink)
select sink, source, sink,
"This $@ is not configured to prevent an External Entity Expansion attack.", source, "XML parser"
"This $@ is not configured to prevent an External Entity Expansion (XXE) attack.", source, "XML parser"