C++: Support the SAX2XMLReader interface.

This commit is contained in:
Geoffrey White
2022-05-03 17:56:27 +01:00
parent c4bc7050a9
commit 6b5a1921dd
3 changed files with 86 additions and 4 deletions

View File

@@ -64,6 +64,13 @@ class SAXParserClass extends Class {
SAXParserClass() { this.hasName("SAXParser") }
}
/**
* The `SAX2XMLReader` class.
*/
class SAX2XMLReader extends Class {
SAX2XMLReader() { this.hasName("SAX2XMLReader") }
}
/**
* Gets a valid flow state for `AbstractDOMParser` or `SAXParser` flow.
*
@@ -168,12 +175,57 @@ class CreateEntityReferenceNodesTranformer extends XXEFlowStateTranformer {
}
/**
* The `AbstractDOMParser.parse` or `SAXParser.parse` method.
* The `XMLUni.fgXercesDisableDefaultEntityResolution` constant.
*/
class FeatureDisableDefaultEntityResolution extends Variable {
FeatureDisableDefaultEntityResolution() {
this.getName() = "fgXercesDisableDefaultEntityResolution" and
this.getDeclaringType().getName() = "XMLUni"
}
}
/**
* A flow state transformer for a call to `SAX2XMLReader.setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, *)`. Transforms the flow
* state through the qualifier according to this setting.
*/
class SetFeatureTranformer extends XXEFlowStateTranformer {
Expr newValue;
SetFeatureTranformer() {
exists(Call call, Function f |
call.getTarget() = f and
f.getDeclaringType() instanceof SAX2XMLReader and
f.hasName("setFeature") and
this = call.getQualifier() and
globalValueNumber(call.getArgument(0)).getAnExpr().(VariableAccess).getTarget() instanceof
FeatureDisableDefaultEntityResolution and
newValue = call.getArgument(1)
)
}
final override XXEFlowState transform(XXEFlowState flowstate) {
exists(int createEntityReferenceNodes |
encodeXercesFlowState(flowstate, _, createEntityReferenceNodes) and
(
globalValueNumber(newValue).getAnExpr().getValue().toInt() = 1 and // true
encodeXercesFlowState(result, 1, createEntityReferenceNodes)
or
not globalValueNumber(newValue).getAnExpr().getValue().toInt() = 1 and // false or unknown
encodeXercesFlowState(result, 0, createEntityReferenceNodes)
)
)
}
}
/**
* The `AbstractDOMParser.parse`, `SAXParser.parse` or `SAX2XMLReader.parse`
* method.
*/
class ParseFunction extends Function {
ParseFunction() {
this.getClassAndName("parse") instanceof AbstractDOMParserClass or
this.getClassAndName("parse") instanceof SAXParserClass
this.getClassAndName("parse") instanceof SAXParserClass or
this.getClassAndName("parse") instanceof SAX2XMLReader
}
}
@@ -188,6 +240,17 @@ class CreateLSParser extends Function {
}
}
/**
* The `createXMLReader` function that returns a newly created `SAX2XMLReader`
* object.
*/
class CreateXMLReader extends Function {
CreateXMLReader() {
this.hasName("createXMLReader") and
this.getUnspecifiedType().(PointerType).getBaseType() instanceof SAX2XMLReader // returns a `SAX2XMLReader *`.
}
}
/**
* A call to a `libxml2` function that parses XML.
*/
@@ -256,6 +319,13 @@ class XXEConfiguration extends DataFlow::Configuration {
encodeXercesFlowState(flowstate, 0, 1) // default configuration
)
or
// source is the result of a call to `createXMLReader`.
exists(Call call |
call.getTarget() instanceof CreateXMLReader and
call = node.asExpr() and
encodeXercesFlowState(flowstate, 0, 1) // default configuration
)
or
// source is an `options` argument on a `libxml2` parse call that specifies
// at least one unsafe option.
//