mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Add XMLDocument sinks
This commit is contained in:
@@ -20,8 +20,8 @@ class XxeAdditionalTaintStep extends Unit {
|
||||
}
|
||||
|
||||
/** The XML argument of a `XMLParser` vulnerable to XXE. */
|
||||
private class DefaultXxeSink extends XxeSink {
|
||||
DefaultXxeSink() {
|
||||
private class XmlParserXxeSink extends XxeSink {
|
||||
XmlParserXxeSink() {
|
||||
this.asExpr() = any(Argument a | a.getApplyExpr() instanceof VulnerableParser).getExpr()
|
||||
}
|
||||
}
|
||||
@@ -67,3 +67,26 @@ private class XmlParserRef extends Expr {
|
||||
private class XmlParserType extends NominalType {
|
||||
XmlParserType() { this.getFullName() = "XMLParser" }
|
||||
}
|
||||
|
||||
/** The XML argument of a `XMLDocument` vulnerable to XXE. */
|
||||
private class XmlDocumentXxeSink extends XxeSink {
|
||||
XmlDocumentXxeSink() { this.asExpr() = any(VulnerableXmlDocument d).getArgument(0).getExpr() }
|
||||
}
|
||||
|
||||
/** An `XMLDocument` that sets `nodeLoadExternalEntitiesAlways` in its options. */
|
||||
private class VulnerableXmlDocument extends ApplyExpr {
|
||||
VulnerableXmlDocument() {
|
||||
this.getStaticTarget().(ConstructorDecl).getEnclosingDecl().(NominalTypeDecl).getFullName() =
|
||||
"XMLDocument" and
|
||||
this.getArgument(1).getExpr().(ArrayExpr).getAnElement().(MemberRefExpr).getMember() instanceof
|
||||
NodeLoadExternalEntitiesAlways
|
||||
}
|
||||
}
|
||||
|
||||
/** The option `XMLNode.Options.nodeLoadExternalEntitiesAlways`. */
|
||||
private class NodeLoadExternalEntitiesAlways extends VarDecl {
|
||||
NodeLoadExternalEntitiesAlways() {
|
||||
this.getName() = "nodeLoadExternalEntitiesAlways" and
|
||||
this.getEnclosingDecl().(StructDecl).getFullName() = "XMLNode.Options"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// --- stubs ---
|
||||
|
||||
class Data {
|
||||
init<S>(_ elements: S) {}
|
||||
}
|
||||
|
||||
struct URL {
|
||||
init?(string: String) {}
|
||||
}
|
||||
|
||||
extension String {
|
||||
init(contentsOf: URL) {
|
||||
let data = ""
|
||||
self.init(data)
|
||||
}
|
||||
}
|
||||
|
||||
class XMLNode {
|
||||
struct Options : OptionSet {
|
||||
let rawValue: Int
|
||||
static let nodeLoadExternalEntitiesAlways = XMLNode.Options(rawValue: 1 << 0)
|
||||
static let nodeLoadExternalEntitiesNever = XMLNode.Options(rawValue: 1 << 1)
|
||||
}
|
||||
}
|
||||
|
||||
class XMLElement {}
|
||||
|
||||
class XMLDocument {
|
||||
init(contentsOf: URL, options: XMLNode.Options = []) {}
|
||||
init(data: Data, options: XMLNode.Options = []) {}
|
||||
init(rootElement: XMLElement?) {}
|
||||
init(xmlString: String, options: XMLNode.Options = []) {}
|
||||
}
|
||||
|
||||
// --- tests ---
|
||||
|
||||
func testUrl() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteUrl = URL(string: remoteString)!
|
||||
let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=39
|
||||
}
|
||||
|
||||
func testUrlSafeImplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteUrl = URL(string: remoteString)!
|
||||
let _ = XMLDocument(contentsOf: remoteUrl, options: []) // NO XXE: document doesn't enable external entities
|
||||
}
|
||||
|
||||
func testUrlSafeExplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteUrl = URL(string: remoteString)!
|
||||
let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities
|
||||
}
|
||||
|
||||
func testData() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteData = Data(remoteString)
|
||||
let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=57
|
||||
}
|
||||
|
||||
func testDataSafeImplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteData = Data(remoteString)
|
||||
let _ = XMLDocument(data: remoteData, options: []) // NO XXE: document doesn't enable external entities
|
||||
}
|
||||
|
||||
func testDataSafeExplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteData = Data(remoteString)
|
||||
let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities
|
||||
}
|
||||
|
||||
func testString() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=75
|
||||
}
|
||||
|
||||
func testStringSafeImplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let _ = XMLDocument(xmlString: remoteString, options: []) // NO XXE: document doesn't enable external entities
|
||||
}
|
||||
|
||||
func testStringSafeExplicit() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities
|
||||
}
|
||||
Reference in New Issue
Block a user