Skip to content

Commit 5552834

Browse files
authored
Merge pull request #9 from RasmusWL/WIP
Rasmus' rewrite of github#6112 See github#6112 (review)
2 parents 518e2ae + ef045a6 commit 5552834

26 files changed

+1410
-847
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @name SimpleXMLRPCServer DoS vulnerability
3+
* @description SimpleXMLRPCServer is vulnerable to DoS attacks from untrusted user input
4+
* @kind problem
5+
* @problem.severity warning
6+
* @precision high
7+
* @id py/simple-xml-rpc-server-dos
8+
* @tags security
9+
* external/cwe/cwe-776
10+
*/
11+
12+
private import python
13+
private import experimental.semmle.python.Concepts
14+
private import semmle.python.ApiGraphs
15+
16+
from DataFlow::CallCfgNode call, string kinds
17+
where
18+
call = API::moduleImport("xmlrpc").getMember("server").getMember("SimpleXMLRPCServer").getACall() and
19+
kinds =
20+
strictconcat(XML::XMLVulnerabilityKind kind |
21+
kind.isBillionLaughs() or kind.isQuadraticBlowup()
22+
|
23+
kind, ", "
24+
)
25+
select call, "SimpleXMLRPCServer is vulnerable to: " + kinds + "."

python/ql/src/experimental/Security/CWE-611/XmlEntityInjection.ql

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@ import python
1515
import experimental.semmle.python.security.dataflow.XmlEntityInjection
1616
import DataFlow::PathGraph
1717

18-
from DataFlow::PathNode source, DataFlow::PathNode sink, string kind
19-
where XmlEntityInjection::xmlEntityInjectionVulnerable(source, sink, kind)
18+
from
19+
XmlEntityInjection::XmlEntityInjectionConfiguration config, DataFlow::PathNode source,
20+
DataFlow::PathNode sink, string kinds
21+
where
22+
config.hasFlowPath(source, sink) and
23+
kinds =
24+
strictconcat(string kind |
25+
kind = sink.getNode().(XmlEntityInjection::Sink).getVulnerableKind()
26+
|
27+
kind, ", "
28+
)
2029
select sink.getNode(), source, sink,
21-
"$@ XML input is constructed from a $@ and is vulnerable to " + kind + ".", sink.getNode(),
30+
"$@ XML input is constructed from a $@ and is vulnerable to: " + kinds + ".", sink.getNode(),
2231
"This", source.getNode(), "user-provided value"

python/ql/src/experimental/semmle/python/Concepts.qll

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,69 +16,53 @@ private import experimental.semmle.python.Frameworks
1616

1717
module XML {
1818
/**
19-
* A data-flow node that collects functions parsing XML.
19+
* A kind of XML vulnerability.
2020
*
21-
* Extend this class to model new APIs. If you want to refine existing API models,
22-
* extend `XMLParsing` instead.
21+
* See https://pypi.org/project/defusedxml/#python-xml-libraries
2322
*/
24-
class XMLParsing extends DataFlow::Node instanceof XMLParsing::Range {
25-
/**
26-
* Gets the argument containing the content to parse.
27-
*/
28-
DataFlow::Node getAnInput() { result = super.getAnInput() }
23+
class XMLVulnerabilityKind extends string {
24+
XMLVulnerabilityKind() {
25+
this in ["Billion Laughs", "Quadratic Blowup", "XXE", "DTD retrieval"]
26+
}
2927

30-
/**
31-
* Holds if the parsing method or the parser holding it is vulnerable to `kind`.
32-
*/
33-
predicate vulnerable(string kind) { super.vulnerable(kind) }
34-
}
28+
/** Holds for Billion Laughs vulnerability kind. */
29+
predicate isBillionLaughs() { this = "Billion Laughs" }
3530

36-
/** Provides classes for modeling XML parsing APIs. */
37-
module XMLParsing {
38-
/**
39-
* A data-flow node that collects functions parsing XML.
40-
*
41-
* Extend this class to model new APIs. If you want to refine existing API models,
42-
* extend `XMLParsing` instead.
43-
*/
44-
abstract class Range extends DataFlow::Node {
45-
/**
46-
* Gets the argument containing the content to parse.
47-
*/
48-
abstract DataFlow::Node getAnInput();
31+
/** Holds for Quadratic Blowup vulnerability kind. */
32+
predicate isQuadraticBlowup() { this = "Quadratic Blowup" }
4933

50-
/**
51-
* Holds if the parsing method or the parser holding it is vulnerable to `kind`.
52-
*/
53-
abstract predicate vulnerable(string kind);
54-
}
34+
/** Holds for XXE vulnerability kind. */
35+
predicate isXxe() { this = "XXE" }
36+
37+
/** Holds for DTD retrieval vulnerability kind. */
38+
predicate isDtdRetrieval() { this = "DTD retrieval" }
5539
}
5640

5741
/**
58-
* A data-flow node that collects XML parsers.
42+
* A data-flow node that parses XML.
5943
*
6044
* Extend this class to model new APIs. If you want to refine existing API models,
61-
* extend `XMLParser` instead.
45+
* extend `XMLParsing` instead.
6246
*/
63-
class XMLParser extends DataFlow::Node instanceof XMLParser::Range {
47+
class XMLParsing extends DataFlow::Node instanceof XMLParsing::Range {
6448
/**
6549
* Gets the argument containing the content to parse.
6650
*/
6751
DataFlow::Node getAnInput() { result = super.getAnInput() }
6852

6953
/**
70-
* Holds if the parser is vulnerable to `kind`.
54+
* Holds if this XML parsing is vulnerable to `kind`.
7155
*/
72-
predicate vulnerable(string kind) { super.vulnerable(kind) }
56+
predicate vulnerableTo(XMLVulnerabilityKind kind) { super.vulnerableTo(kind) }
7357
}
7458

75-
/** Provides classes for modeling XML parsers. */
76-
module XMLParser {
59+
/** Provides classes for modeling XML parsing APIs. */
60+
module XMLParsing {
7761
/**
78-
* A data-flow node that collects XML parsers.
62+
* A data-flow node that parses XML.
7963
*
8064
* Extend this class to model new APIs. If you want to refine existing API models,
81-
* extend `XMLParser` instead.
65+
* extend `XMLParsing` instead.
8266
*/
8367
abstract class Range extends DataFlow::Node {
8468
/**
@@ -87,9 +71,9 @@ module XML {
8771
abstract DataFlow::Node getAnInput();
8872

8973
/**
90-
* Holds if the parser is vulnerable to `kind`.
74+
* Holds if this XML parsing is vulnerable to `kind`.
9175
*/
92-
abstract predicate vulnerable(string kind);
76+
abstract predicate vulnerableTo(XMLVulnerabilityKind kind);
9377
}
9478
}
9579
}

0 commit comments

Comments
 (0)