Skip to content

Commit e8649d8

Browse files
committed
python: model (etree from) lxml
1 parent 3f36ccb commit e8649d8

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

docs/codeql/support/reusables/frameworks.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,4 @@ Python built-in support
204204
pycryptodomex, Cryptography library
205205
rsa, Cryptography library
206206
MarkupSafe, Escaping Library
207+
lxml, XML processing library

python/ql/lib/semmle/python/Frameworks.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ private import semmle.python.frameworks.FlaskSqlAlchemy
2222
private import semmle.python.frameworks.Idna
2323
private import semmle.python.frameworks.Invoke
2424
private import semmle.python.frameworks.Jmespath
25+
private import semmle.python.frameworks.Lxml
2526
private import semmle.python.frameworks.MarkupSafe
2627
private import semmle.python.frameworks.Multidict
2728
private import semmle.python.frameworks.Mysql
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `lxml` PyPI package.
3+
*
4+
* See
5+
* - https://pypi.org/project/lxml/
6+
* - https://lxml.de/tutorial.html
7+
*/
8+
9+
private import python
10+
private import semmle.python.dataflow.new.DataFlow
11+
private import semmle.python.Concepts
12+
private import semmle.python.ApiGraphs
13+
14+
/**
15+
* Provides classes modeling security-relevant aspects of the `lxml` PyPI package
16+
*
17+
* See
18+
* - https://pypi.org/project/lxml/
19+
* - https://lxml.de/tutorial.html
20+
*/
21+
private module Lxml {
22+
/**
23+
* A class constructor compiling an XPath expression.
24+
*
25+
* from lxml import etree
26+
* root = etree.XML("<xmlContent>")
27+
* find_text = etree.XPath("`sink`")
28+
* find_text = etree.ETXPath("`sink`")
29+
*
30+
* See
31+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.XPath
32+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.ETXPath
33+
*/
34+
private class XPathClassCall extends XPathConstruction::Range, DataFlow::CallCfgNode {
35+
XPathClassCall() {
36+
this = API::moduleImport("lxml").getMember("etree").getMember(["XPath", "ETXPath"]).getACall()
37+
}
38+
39+
override DataFlow::Node getXPath() { result in [this.getArg(0), this.getArgByName("path")] }
40+
41+
override string getName() { result = "Lxml.etree" }
42+
}
43+
44+
/**
45+
* A call to the `xpath` method of a parsed document.
46+
*
47+
* from lxml import etree
48+
* root = etree.fromstring(file(XML_DB).read(), XMLParser())
49+
* find_text = root.xpath("`sink`")
50+
*
51+
* See https://lxml.de/apidoc/lxml.etree.html#lxml.etree._ElementTree.xpath
52+
* as well as
53+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.parse
54+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.fromstring
55+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.fromstringlist
56+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.HTML
57+
* - https://lxml.de/apidoc/lxml.etree.html#lxml.etree.XML
58+
*/
59+
class XPathCall extends XPathExecution::Range, DataFlow::CallCfgNode {
60+
XPathCall() {
61+
this =
62+
API::moduleImport("lxml")
63+
.getMember("etree")
64+
.getMember(["parse", "fromstring", "fromstringlist", "HTML", "XML"])
65+
.getReturn()
66+
.getMember("xpath")
67+
.getACall()
68+
}
69+
70+
override DataFlow::Node getXPath() { result in [this.getArg(0), this.getArgByName("_path")] }
71+
72+
// TODO: implement when we get call nodes
73+
override DataFlow::Node getTree() { none() }
74+
75+
override string getName() { result = "Lxml.etree" }
76+
}
77+
}

0 commit comments

Comments
 (0)