Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e005a5c

Browse files
committed
Python: Promote XMLParsing concept
1 parent 9caf4be commit e005a5c

6 files changed

Lines changed: 70 additions & 76 deletions

File tree

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,68 @@ module XML {
550550
abstract string getName();
551551
}
552552
}
553+
554+
/**
555+
* A kind of XML vulnerability.
556+
*
557+
* See overview of kinds at https://pypi.org/project/defusedxml/#python-xml-libraries
558+
*/
559+
class XMLVulnerabilityKind extends string {
560+
XMLVulnerabilityKind() {
561+
this in ["Billion Laughs", "Quadratic Blowup", "XXE", "DTD retrieval"]
562+
}
563+
564+
/** Holds for Billion Laughs vulnerability kind. */
565+
predicate isBillionLaughs() { this = "Billion Laughs" }
566+
567+
/** Holds for Quadratic Blowup vulnerability kind. */
568+
predicate isQuadraticBlowup() { this = "Quadratic Blowup" }
569+
570+
/** Holds for XXE vulnerability kind. */
571+
predicate isXxe() { this = "XXE" }
572+
573+
/** Holds for DTD retrieval vulnerability kind. */
574+
predicate isDtdRetrieval() { this = "DTD retrieval" }
575+
}
576+
577+
/**
578+
* A data-flow node that parses XML.
579+
*
580+
* Extend this class to model new APIs. If you want to refine existing API models,
581+
* extend `XMLParsing` instead.
582+
*/
583+
class XMLParsing extends DataFlow::Node instanceof XMLParsing::Range {
584+
/**
585+
* Gets the argument containing the content to parse.
586+
*/
587+
DataFlow::Node getAnInput() { result = super.getAnInput() }
588+
589+
/**
590+
* Holds if this XML parsing is vulnerable to `kind`.
591+
*/
592+
predicate vulnerableTo(XMLVulnerabilityKind kind) { super.vulnerableTo(kind) }
593+
}
594+
595+
/** Provides classes for modeling XML parsing APIs. */
596+
module XMLParsing {
597+
/**
598+
* A data-flow node that parses XML.
599+
*
600+
* Extend this class to model new APIs. If you want to refine existing API models,
601+
* extend `XMLParsing` instead.
602+
*/
603+
abstract class Range extends DataFlow::Node {
604+
/**
605+
* Gets the argument containing the content to parse.
606+
*/
607+
abstract DataFlow::Node getAnInput();
608+
609+
/**
610+
* Holds if this XML parsing is vulnerable to `kind`.
611+
*/
612+
abstract predicate vulnerableTo(XMLVulnerabilityKind kind);
613+
}
614+
}
553615
}
554616

555617
/** Provides classes for modeling LDAP-related APIs. */

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

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,6 @@ private import semmle.python.dataflow.new.RemoteFlowSources
1414
private import semmle.python.dataflow.new.TaintTracking
1515
private import experimental.semmle.python.Frameworks
1616

17-
/**
18-
* Since there is both XML module in normal and experimental Concepts,
19-
* we have to rename the experimental module as this.
20-
*/
21-
module ExperimentalXML {
22-
/**
23-
* A kind of XML vulnerability.
24-
*
25-
* See https://pypi.org/project/defusedxml/#python-xml-libraries
26-
*/
27-
class XMLVulnerabilityKind extends string {
28-
XMLVulnerabilityKind() {
29-
this in ["Billion Laughs", "Quadratic Blowup", "XXE", "DTD retrieval"]
30-
}
31-
32-
/** Holds for Billion Laughs vulnerability kind. */
33-
predicate isBillionLaughs() { this = "Billion Laughs" }
34-
35-
/** Holds for Quadratic Blowup vulnerability kind. */
36-
predicate isQuadraticBlowup() { this = "Quadratic Blowup" }
37-
38-
/** Holds for XXE vulnerability kind. */
39-
predicate isXxe() { this = "XXE" }
40-
41-
/** Holds for DTD retrieval vulnerability kind. */
42-
predicate isDtdRetrieval() { this = "DTD retrieval" }
43-
}
44-
45-
/**
46-
* A data-flow node that parses XML.
47-
*
48-
* Extend this class to model new APIs. If you want to refine existing API models,
49-
* extend `XMLParsing` instead.
50-
*/
51-
class XMLParsing extends DataFlow::Node instanceof XMLParsing::Range {
52-
/**
53-
* Gets the argument containing the content to parse.
54-
*/
55-
DataFlow::Node getAnInput() { result = super.getAnInput() }
56-
57-
/**
58-
* Holds if this XML parsing is vulnerable to `kind`.
59-
*/
60-
predicate vulnerableTo(XMLVulnerabilityKind kind) { super.vulnerableTo(kind) }
61-
}
62-
63-
/** Provides classes for modeling XML parsing APIs. */
64-
module XMLParsing {
65-
/**
66-
* A data-flow node that parses XML.
67-
*
68-
* Extend this class to model new APIs. If you want to refine existing API models,
69-
* extend `XMLParsing` instead.
70-
*/
71-
abstract class Range extends DataFlow::Node {
72-
/**
73-
* Gets the argument containing the content to parse.
74-
*/
75-
abstract DataFlow::Node getAnInput();
76-
77-
/**
78-
* Holds if this XML parsing is vulnerable to `kind`.
79-
*/
80-
abstract predicate vulnerableTo(XMLVulnerabilityKind kind);
81-
}
82-
}
83-
}
84-
8517
/** Provides classes for modeling LDAP query execution-related APIs. */
8618
module LdapQuery {
8719
/**

python/ql/src/experimental/semmle/python/frameworks/Xml.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55

66
private import python
77
private import semmle.python.dataflow.new.DataFlow
8-
private import experimental.semmle.python.Concepts
8+
private import semmle.python.Concepts
99
private import semmle.python.ApiGraphs
1010

11-
module XML = ExperimentalXML;
12-
1311
private module XmlEtree {
1412
/**
1513
* Provides models for `xml.etree` parsers

python/ql/src/experimental/semmle/python/security/dataflow/XmlBombCustomizations.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
private import python
88
private import semmle.python.dataflow.new.DataFlow
9-
private import experimental.semmle.python.Concepts
9+
private import semmle.python.Concepts
10+
import experimental.semmle.python.frameworks.Xml // needed until modeling have been promoted
1011
private import semmle.python.dataflow.new.RemoteFlowSources
1112

1213
/**
@@ -40,7 +41,7 @@ module XmlBomb {
4041
*/
4142
class XmlParsingWithEntityResolution extends Sink {
4243
XmlParsingWithEntityResolution() {
43-
exists(ExperimentalXML::XMLParsing parsing, ExperimentalXML::XMLVulnerabilityKind kind |
44+
exists(XML::XMLParsing parsing, XML::XMLVulnerabilityKind kind |
4445
(kind.isBillionLaughs() or kind.isQuadraticBlowup()) and
4546
parsing.vulnerableTo(kind) and
4647
this = parsing.getAnInput()

python/ql/src/experimental/semmle/python/security/dataflow/XxeCustomizations.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
private import python
88
private import semmle.python.dataflow.new.DataFlow
9-
private import experimental.semmle.python.Concepts
9+
private import semmle.python.Concepts
10+
import experimental.semmle.python.frameworks.Xml // needed until modeling have been promoted
1011
private import semmle.python.dataflow.new.RemoteFlowSources
1112

1213
/**
@@ -40,7 +41,7 @@ module Xxe {
4041
*/
4142
class XmlParsingWithExternalEntityResolution extends Sink {
4243
XmlParsingWithExternalEntityResolution() {
43-
exists(ExperimentalXML::XMLParsing parsing, ExperimentalXML::XMLVulnerabilityKind kind |
44+
exists(XML::XMLParsing parsing, XML::XMLVulnerabilityKind kind |
4445
kind.isXxe() and
4546
parsing.vulnerableTo(kind) and
4647
this = parsing.getAnInput()

python/ql/test/experimental/library-tests/frameworks/XML/ExperimentalXmlConceptsTests.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import python
2-
import experimental.semmle.python.Concepts
2+
import semmle.python.Concepts
33
import experimental.semmle.python.frameworks.Xml
44
import semmle.python.dataflow.new.DataFlow
55
import TestUtilities.InlineExpectationsTest

0 commit comments

Comments
 (0)