Skip to content

Commit 34b8af3

Browse files
committed
Move structure to LDAP.qll
1 parent c2b96b3 commit 34b8af3

File tree

2 files changed

+153
-143
lines changed

2 files changed

+153
-143
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the LDAP libraries.
3+
*/
4+
5+
private import python
6+
private import semmle.python.dataflow.new.DataFlow
7+
private import semmle.python.dataflow.new.TaintTracking
8+
private import semmle.python.dataflow.new.RemoteFlowSources
9+
private import experimental.semmle.python.Concepts
10+
private import semmle.python.ApiGraphs
11+
12+
/**
13+
* Provides models for Python's ldap-related libraries.
14+
*/
15+
private module LDAP {
16+
/**
17+
* Provides models for Python's `ldap` library.
18+
*
19+
* See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html
20+
*/
21+
private module LDAP2 {
22+
/**
23+
* List of `ldap` methods used to execute a query.
24+
*
25+
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#functions
26+
*/
27+
private class LDAP2QueryMethods extends string {
28+
LDAP2QueryMethods() {
29+
this in ["search", "search_s", "search_st", "search_ext", "search_ext_s"]
30+
}
31+
}
32+
33+
/**
34+
* A class to find `ldap` methods executing a query.
35+
*
36+
* See `LDAP2QueryMethods`
37+
*/
38+
private class LDAP2Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
39+
DataFlow::Node ldapNode;
40+
41+
LDAP2Query() {
42+
exists(DataFlow::AttrRead searchMethod |
43+
this.getFunction() = searchMethod and
44+
API::moduleImport("ldap").getMember("initialize").getACall() =
45+
searchMethod.getObject().getALocalSource() and
46+
searchMethod.getAttributeName() instanceof LDAP2QueryMethods and
47+
(
48+
ldapNode = this.getArg(0)
49+
or
50+
(
51+
ldapNode = this.getArg(2) or
52+
ldapNode = this.getArgByName("filterstr")
53+
)
54+
)
55+
)
56+
}
57+
58+
override DataFlow::Node getLDAPNode() { result = ldapNode }
59+
}
60+
61+
/**
62+
* A class to find calls to `ldap.dn.escape_dn_chars`.
63+
*
64+
* See https://github.com/python-ldap/python-ldap/blob/7ce471e238cdd9a4dd8d17baccd1c9e05e6f894a/Lib/ldap/dn.py#L17
65+
*/
66+
private class LDAP2EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
67+
LDAP2EscapeDNCall() {
68+
this = API::moduleImport("ldap").getMember("dn").getMember("escape_dn_chars").getACall()
69+
}
70+
71+
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
72+
}
73+
74+
/**
75+
* A class to find calls to `ldap.filter.escape_filter_chars`.
76+
*
77+
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-filter.html#ldap.filter.escape_filter_chars
78+
*/
79+
private class LDAP2EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
80+
LDAP2EscapeFilterCall() {
81+
this =
82+
API::moduleImport("ldap").getMember("filter").getMember("escape_filter_chars").getACall()
83+
}
84+
85+
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
86+
}
87+
}
88+
89+
/**
90+
* Provides models for Python's `ldap3` library.
91+
*
92+
* See https://pypi.org/project/ldap3/
93+
*/
94+
private module LDAP3 {
95+
/**
96+
* A class to find `ldap3` methods executing a query.
97+
*/
98+
private class LDAP3Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
99+
DataFlow::Node ldapNode;
100+
101+
LDAP3Query() {
102+
exists(DataFlow::AttrRead searchMethod |
103+
this.getFunction() = searchMethod and
104+
API::moduleImport("ldap3").getMember("Connection").getACall() =
105+
searchMethod.getObject().getALocalSource() and
106+
searchMethod.getAttributeName() = "search" and
107+
(
108+
ldapNode = this.getArg(0) or
109+
ldapNode = this.getArg(1)
110+
)
111+
)
112+
}
113+
114+
override DataFlow::Node getLDAPNode() { result = ldapNode }
115+
}
116+
117+
/**
118+
* A class to find calls to `ldap3.utils.dn.escape_rdn`.
119+
*
120+
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/dn.py#L390
121+
*/
122+
private class LDAP3EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
123+
LDAP3EscapeDNCall() {
124+
this =
125+
API::moduleImport("ldap3")
126+
.getMember("utils")
127+
.getMember("dn")
128+
.getMember("escape_rdn")
129+
.getACall()
130+
}
131+
132+
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
133+
}
134+
135+
/**
136+
* A class to find calls to `ldap3.utils.conv.escape_filter_chars`.
137+
*
138+
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/conv.py#L91
139+
*/
140+
private class LDAP3EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
141+
LDAP3EscapeFilterCall() {
142+
this =
143+
API::moduleImport("ldap3")
144+
.getMember("utils")
145+
.getMember("conv")
146+
.getMember("escape_filter_chars")
147+
.getACall()
148+
}
149+
150+
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
151+
}
152+
}
153+
}

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

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -9,146 +9,3 @@ private import semmle.python.dataflow.new.TaintTracking
99
private import semmle.python.dataflow.new.RemoteFlowSources
1010
private import experimental.semmle.python.Concepts
1111
private import semmle.python.ApiGraphs
12-
13-
/**
14-
* Provides models for Python's ldap-related libraries.
15-
*/
16-
private module LDAP {
17-
/**
18-
* Provides models for Python's `ldap` library.
19-
*
20-
* See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html
21-
*/
22-
private module LDAP2 {
23-
/**
24-
* List of `ldap` methods used to execute a query.
25-
*
26-
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#functions
27-
*/
28-
private class LDAP2QueryMethods extends string {
29-
LDAP2QueryMethods() {
30-
this in ["search", "search_s", "search_st", "search_ext", "search_ext_s"]
31-
}
32-
}
33-
34-
/**
35-
* A class to find `ldap` methods executing a query.
36-
*
37-
* See `LDAP2QueryMethods`
38-
*/
39-
private class LDAP2Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
40-
DataFlow::Node ldapNode;
41-
42-
LDAP2Query() {
43-
exists(DataFlow::AttrRead searchMethod |
44-
this.getFunction() = searchMethod and
45-
API::moduleImport("ldap").getMember("initialize").getACall() =
46-
searchMethod.getObject().getALocalSource() and
47-
searchMethod.getAttributeName() instanceof LDAP2QueryMethods and
48-
(
49-
ldapNode = this.getArg(0)
50-
or
51-
(
52-
ldapNode = this.getArg(2) or
53-
ldapNode = this.getArgByName("filterstr")
54-
)
55-
)
56-
)
57-
}
58-
59-
override DataFlow::Node getLDAPNode() { result = ldapNode }
60-
}
61-
62-
/**
63-
* A class to find calls to `ldap.dn.escape_dn_chars`.
64-
*
65-
* See https://github.com/python-ldap/python-ldap/blob/7ce471e238cdd9a4dd8d17baccd1c9e05e6f894a/Lib/ldap/dn.py#L17
66-
*/
67-
private class LDAP2EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
68-
LDAP2EscapeDNCall() {
69-
this = API::moduleImport("ldap").getMember("dn").getMember("escape_dn_chars").getACall()
70-
}
71-
72-
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
73-
}
74-
75-
/**
76-
* A class to find calls to `ldap.filter.escape_filter_chars`.
77-
*
78-
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-filter.html#ldap.filter.escape_filter_chars
79-
*/
80-
private class LDAP2EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
81-
LDAP2EscapeFilterCall() {
82-
this =
83-
API::moduleImport("ldap").getMember("filter").getMember("escape_filter_chars").getACall()
84-
}
85-
86-
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
87-
}
88-
}
89-
90-
/**
91-
* Provides models for Python's `ldap3` library.
92-
*
93-
* See https://pypi.org/project/ldap3/
94-
*/
95-
private module LDAP3 {
96-
/**
97-
* A class to find `ldap3` methods executing a query.
98-
*/
99-
private class LDAP3Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
100-
DataFlow::Node ldapNode;
101-
102-
LDAP3Query() {
103-
exists(DataFlow::AttrRead searchMethod |
104-
this.getFunction() = searchMethod and
105-
API::moduleImport("ldap3").getMember("Connection").getACall() =
106-
searchMethod.getObject().getALocalSource() and
107-
searchMethod.getAttributeName() = "search" and
108-
(
109-
ldapNode = this.getArg(0) or
110-
ldapNode = this.getArg(1)
111-
)
112-
)
113-
}
114-
115-
override DataFlow::Node getLDAPNode() { result = ldapNode }
116-
}
117-
118-
/**
119-
* A class to find calls to `ldap3.utils.dn.escape_rdn`.
120-
*
121-
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/dn.py#L390
122-
*/
123-
private class LDAP3EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
124-
LDAP3EscapeDNCall() {
125-
this =
126-
API::moduleImport("ldap3")
127-
.getMember("utils")
128-
.getMember("dn")
129-
.getMember("escape_rdn")
130-
.getACall()
131-
}
132-
133-
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
134-
}
135-
136-
/**
137-
* A class to find calls to `ldap3.utils.conv.escape_filter_chars`.
138-
*
139-
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/conv.py#L91
140-
*/
141-
private class LDAP3EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
142-
LDAP3EscapeFilterCall() {
143-
this =
144-
API::moduleImport("ldap3")
145-
.getMember("utils")
146-
.getMember("conv")
147-
.getMember("escape_filter_chars")
148-
.getACall()
149-
}
150-
151-
override DataFlow::Node getEscapeNode() { result = this.getArg(0) }
152-
}
153-
}
154-
}

0 commit comments

Comments
 (0)