@@ -19,6 +19,20 @@ private module LDAP {
19
19
* See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html
20
20
*/
21
21
private module LDAP2 {
22
+ /** Gets a reference to the `ldap` module. */
23
+ API:: Node ldap ( ) { result = API:: moduleImport ( "ldap" ) }
24
+
25
+ /** Returns a `ldap` module instance */
26
+ API:: Node ldapInitialize ( ) { result = ldap ( ) .getMember ( "initialize" ) }
27
+
28
+ /** Gets a reference to a `ldap` operation. */
29
+ private DataFlow:: TypeTrackingNode ldapOperation ( DataFlow:: TypeTracker t ) {
30
+ t .start ( ) and
31
+ result .( DataFlow:: AttrRead ) .getObject ( ) .getALocalSource ( ) = ldapInitialize ( ) .getACall ( )
32
+ or
33
+ exists ( DataFlow:: TypeTracker t2 | result = ldapOperation ( t2 ) .track ( t2 , t ) )
34
+ }
35
+
22
36
/**
23
37
* List of `ldap` methods used to execute a query.
24
38
*
@@ -30,32 +44,61 @@ private module LDAP {
30
44
}
31
45
}
32
46
47
+ /** Gets a reference to a `ldap` operation. */
48
+ private DataFlow:: Node ldapOperation ( ) {
49
+ ldapOperation ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )
50
+ }
51
+
52
+ /** Gets a reference to a `ldap` query. */
53
+ private DataFlow:: Node ldapQuery ( ) {
54
+ result = ldapOperation ( ) and
55
+ result .( DataFlow:: AttrRead ) .getAttributeName ( ) instanceof LDAP2QueryMethods
56
+ }
57
+
33
58
/**
34
59
* A class to find `ldap` methods executing a query.
35
60
*
36
61
* See `LDAP2QueryMethods`
37
62
*/
38
63
private class LDAP2Query extends DataFlow:: CallCfgNode , LDAPQuery:: Range {
39
- DataFlow:: Node ldapQuery ;
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
- ldapQuery = this .getArg ( 0 )
49
- or
50
- (
51
- ldapQuery = this .getArg ( 2 ) or
52
- ldapQuery = this .getArgByName ( "filterstr" )
53
- )
54
- )
55
- )
64
+ LDAP2Query ( ) { this .getFunction ( ) = ldapQuery ( ) }
65
+
66
+ override DataFlow:: Node getQuery ( ) {
67
+ result in [ this .getArg ( 0 ) , this .getArg ( 2 ) , this .getArgByName ( "filterstr" ) ]
68
+ }
69
+ }
70
+
71
+ /**
72
+ * List of `ldap` methods used for binding.
73
+ *
74
+ * See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#functions
75
+ */
76
+ private class LDAP2BindMethods extends string {
77
+ LDAP2BindMethods ( ) {
78
+ this in [
79
+ "bind" , "bind_s" , "simple_bind" , "simple_bind_s" , "sasl_interactive_bind_s" ,
80
+ "sasl_non_interactive_bind_s" , "sasl_external_bind_s" , "sasl_gssapi_bind_s"
81
+ ]
56
82
}
83
+ }
57
84
58
- override DataFlow:: Node getQuery ( ) { result = ldapQuery }
85
+ /** Gets a reference to a `ldap` bind. */
86
+ private DataFlow:: Node ldapBind ( ) {
87
+ result = ldapOperation ( ) and
88
+ result .( DataFlow:: AttrRead ) .getAttributeName ( ) instanceof LDAP2BindMethods
89
+ }
90
+
91
+ /**
92
+ * A class to find `ldap` methods binding a connection.
93
+ *
94
+ * See `LDAP2BindMethods`
95
+ */
96
+ private class LDAP2Bind extends DataFlow:: CallCfgNode , LDAPBind:: Range {
97
+ LDAP2Bind ( ) { this .getFunction ( ) = ldapBind ( ) }
98
+
99
+ override DataFlow:: Node getPassword ( ) {
100
+ result in [ this .getArg ( 1 ) , this .getArgByName ( "cred" ) ]
101
+ }
59
102
}
60
103
61
104
/**
@@ -64,9 +107,7 @@ private module LDAP {
64
107
* See https://github.com/python-ldap/python-ldap/blob/7ce471e238cdd9a4dd8d17baccd1c9e05e6f894a/Lib/ldap/dn.py#L17
65
108
*/
66
109
private class LDAP2EscapeDNCall extends DataFlow:: CallCfgNode , LDAPEscape:: Range {
67
- LDAP2EscapeDNCall ( ) {
68
- this = API:: moduleImport ( "ldap" ) .getMember ( "dn" ) .getMember ( "escape_dn_chars" ) .getACall ( )
69
- }
110
+ LDAP2EscapeDNCall ( ) { this = ldap ( ) .getMember ( "dn" ) .getMember ( "escape_dn_chars" ) .getACall ( ) }
70
111
71
112
override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
72
113
}
@@ -78,8 +119,7 @@ private module LDAP {
78
119
*/
79
120
private class LDAP2EscapeFilterCall extends DataFlow:: CallCfgNode , LDAPEscape:: Range {
80
121
LDAP2EscapeFilterCall ( ) {
81
- this =
82
- API:: moduleImport ( "ldap" ) .getMember ( "filter" ) .getMember ( "escape_filter_chars" ) .getACall ( )
122
+ this = ldap ( ) .getMember ( "filter" ) .getMember ( "escape_filter_chars" ) .getACall ( )
83
123
}
84
124
85
125
override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
@@ -92,26 +132,40 @@ private module LDAP {
92
132
* See https://pypi.org/project/ldap3/
93
133
*/
94
134
private module LDAP3 {
135
+ /** Gets a reference to the `ldap3` module. */
136
+ API:: Node ldap3 ( ) { result = API:: moduleImport ( "ldap3" ) }
137
+
138
+ /** Gets a reference to the `ldap3` `utils` module. */
139
+ API:: Node ldap3Utils ( ) { result = ldap3 ( ) .getMember ( "utils" ) }
140
+
141
+ /** Returns a `ldap3` module `Server` instance */
142
+ API:: Node ldap3Server ( ) { result = ldap3 ( ) .getMember ( "Server" ) }
143
+
144
+ /** Returns a `ldap3` module `Connection` instance */
145
+ API:: Node ldap3Connection ( ) { result = ldap3 ( ) .getMember ( "Connection" ) }
146
+
95
147
/**
96
148
* A class to find `ldap3` methods executing a query.
97
149
*/
98
150
private class LDAP3Query extends DataFlow:: CallCfgNode , LDAPQuery:: Range {
99
- DataFlow:: Node ldapQuery ;
100
-
101
151
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
- ldapQuery = this .getArg ( 0 ) or
109
- ldapQuery = this .getArg ( 1 )
110
- )
111
- )
152
+ this .getFunction ( ) .( DataFlow:: AttrRead ) .getObject ( ) .getALocalSource ( ) =
153
+ ldap3Connection ( ) .getACall ( ) and
154
+ this .getFunction ( ) .( DataFlow:: AttrRead ) .getAttributeName ( ) = "search"
112
155
}
113
156
114
- override DataFlow:: Node getQuery ( ) { result = ldapQuery }
157
+ override DataFlow:: Node getQuery ( ) { result in [ this .getArg ( 0 ) , this .getArg ( 1 ) ] }
158
+ }
159
+
160
+ /**
161
+ * A class to find `ldap3` methods binding a connection.
162
+ */
163
+ class LDAP3Bind extends DataFlow:: CallCfgNode , LDAPBind:: Range {
164
+ LDAP3Bind ( ) { this = ldap3Connection ( ) .getACall ( ) }
165
+
166
+ override DataFlow:: Node getPassword ( ) {
167
+ result in [ this .getArg ( 2 ) , this .getArgByName ( "password" ) ]
168
+ }
115
169
}
116
170
117
171
/**
@@ -120,14 +174,7 @@ private module LDAP {
120
174
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/dn.py#L390
121
175
*/
122
176
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
- }
177
+ LDAP3EscapeDNCall ( ) { this = ldap3Utils ( ) .getMember ( "dn" ) .getMember ( "escape_rdn" ) .getACall ( ) }
131
178
132
179
override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
133
180
}
@@ -139,12 +186,7 @@ private module LDAP {
139
186
*/
140
187
private class LDAP3EscapeFilterCall extends DataFlow:: CallCfgNode , LDAPEscape:: Range {
141
188
LDAP3EscapeFilterCall ( ) {
142
- this =
143
- API:: moduleImport ( "ldap3" )
144
- .getMember ( "utils" )
145
- .getMember ( "conv" )
146
- .getMember ( "escape_filter_chars" )
147
- .getACall ( )
189
+ this = ldap3Utils ( ) .getMember ( "conv" ) .getMember ( "escape_filter_chars" ) .getACall ( )
148
190
}
149
191
150
192
override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
0 commit comments