Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7de9214
Upload LDAP Insecure authentication query and tests
jorgectf Mar 18, 2021
3ce0a9c
Move to experimental folder
jorgectf Mar 18, 2021
957b3e1
Precision warn
jorgectf Mar 18, 2021
edb273a
Merge remote-tracking branch 'origin/jorgectf/python/ldapimproperauth…
jorgectf Jul 22, 2021
a34d6d3
Port to ApiGraphs and finish the query
jorgectf Jul 22, 2021
b03e75e
Extend `ldap3`'s `start_tls` and fix tests
jorgectf Jul 22, 2021
f02b6d6
Merge branch 'github:main' into jorgectf/python/ldapinsecureauth
jorgectf Jul 22, 2021
d458464
Apply suggestions from code review
jorgectf Aug 26, 2021
786edb7
Update `.expected`
jorgectf Aug 26, 2021
64b305c
Add `.qhelp` along with its example
jorgectf Aug 26, 2021
1bc16fb
Apply suggestions from code review
jorgectf Sep 7, 2021
ee98c0c
Add `start_tls_s()` comment and use `DataFlow::MethodCallNode` instead
jorgectf Sep 7, 2021
b802d79
Fix `OPT_X_TLS_` mandatory options
jorgectf Sep 7, 2021
8008011
Fix taint tracking comment
jorgectf Sep 7, 2021
4e261c6
Optimize `concatAndCompareAgainstFullHostRegex`
jorgectf Sep 7, 2021
54012eb
Optimize `getFullHostRegex`
jorgectf Sep 12, 2021
18b05bc
Fix tests and add global option
jorgectf Sep 12, 2021
3cf28ad
Merge remote-tracking branch 'origin/main' into jorgectf/python/ldapi…
jorgectf Sep 12, 2021
353c0a9
Add missing comment
jorgectf Sep 12, 2021
2ccc6dc
Merge branch 'main' into jorgectf/python/ldapinsecureauth
jorgectf Sep 14, 2021
b505662
Fix global test and update `.expected`
jorgectf Sep 14, 2021
70489b2
Merge branch 'main' into jorgectf/python/ldapinsecureauth
RasmusWL Sep 23, 2021
ef6e502
Python: Make LDAP global options test better
RasmusWL Sep 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Port to ApiGraphs and finish the query
  • Loading branch information
jorgectf committed Jul 22, 2021
commit a34d6d390ecb8387b3c68bf79cdf9ac3eb7b4a25
192 changes: 0 additions & 192 deletions python/ql/src/experimental/Security/CWE-090/LDAPInsecureAuth.ql

This file was deleted.

20 changes: 20 additions & 0 deletions python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @name Python Insecure LDAP Authentication
* @description Python LDAP Insecure LDAP Authentication
* @kind path-problem
* @problem.severity error
* @id python/insecure-ldap-auth
Comment thread
jorgectf marked this conversation as resolved.
Outdated
* @tags experimental
* security
* external/cwe/cwe-522
Comment thread
jorgectf marked this conversation as resolved.
*/

// determine precision above
import python
import DataFlow::PathGraph
import experimental.semmle.python.security.LDAPInsecureAuth

from LDAPInsecureAuthConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ is authenticated insecurely.", sink.getNode(),
"This LDAP host"
23 changes: 23 additions & 0 deletions python/ql/src/experimental/semmle/python/Concepts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,20 @@ module LDAPBind {
* extend `LDAPBind` instead.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets the argument containing the binding host.
*/
abstract DataFlow::Node getHost();

/**
* Gets the argument containing the binding expression.
*/
abstract DataFlow::Node getPassword();

/**
* Checks if the binding process use SSL.
Comment thread
jorgectf marked this conversation as resolved.
Outdated
*/
abstract predicate useSSL();
}
}

Expand All @@ -174,5 +184,18 @@ class LDAPBind extends DataFlow::Node {

LDAPBind() { this = range }

/**
* Gets the argument containing the binding host.
*/
DataFlow::Node getHost() { result = range.getHost() }

/**
* Gets the argument containing the binding expression.
*/
DataFlow::Node getPassword() { result = range.getPassword() }

/**
* Checks if the binding process use SSL.
Comment thread
jorgectf marked this conversation as resolved.
Outdated
*/
predicate useSSL() { range.useSSL() }
}
54 changes: 54 additions & 0 deletions python/ql/src/experimental/semmle/python/frameworks/LDAP.qll
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,42 @@ private module LDAP {
override DataFlow::Node getPassword() {
result in [this.getArg(1), this.getArgByName("cred")]
}

override DataFlow::Node getHost() {
exists(DataFlow::CallCfgNode initialize |
this.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() = initialize and
initialize = ldapInitialize().getACall() and
result = initialize.getArg(0)
)
}

override predicate useSSL() {
// use initialize to correlate `this` and so avoid FP in several instances
exists(DataFlow::CallCfgNode initialize |
this.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() = initialize and
initialize = ldapInitialize().getACall() and
(
// ldap_connection.start_tls_s()
Comment thread
jorgectf marked this conversation as resolved.
exists(DataFlow::AttrRead startTLS |
Comment thread
RasmusWL marked this conversation as resolved.
Outdated
startTLS.getObject().getALocalSource() = initialize and
startTLS.getAttributeName().matches("%start_tls%")
Comment thread
jorgectf marked this conversation as resolved.
Outdated
)
or
// ldap_connection.set_option(ldap.OPT_X_TLS_%s, True)
// ldap_connection.set_option(ldap.OPT_X_TLS_%s)
Comment thread
jorgectf marked this conversation as resolved.
Outdated
exists(DataFlow::CallCfgNode setOption |
setOption.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() =
initialize and
setOption.getFunction().(DataFlow::AttrRead).getAttributeName() = "set_option" and
setOption.getArg(0) =
ldap().getMember("OPT_X_TLS_" + ["ALLOW", "TRY", "DEMAND", "HARD"]).getAUse() and
Comment thread
RasmusWL marked this conversation as resolved.
Outdated
not DataFlow::exprNode(any(False falseExpr))
.(DataFlow::LocalSourceNode)
.flowsTo(setOption.getArg(1))
)
)
)
}
}

/**
Expand Down Expand Up @@ -166,6 +202,24 @@ private module LDAP {
override DataFlow::Node getPassword() {
result in [this.getArg(2), this.getArgByName("password")]
}

override DataFlow::Node getHost() {
exists(DataFlow::CallCfgNode serverCall |
serverCall = ldap3Server().getACall() and
this.getArg(0).getALocalSource() = serverCall and
result = serverCall.getArg(0)
)
}

override predicate useSSL() {
exists(DataFlow::CallCfgNode serverCall |
serverCall = ldap3Server().getACall() and
this.getArg(0).getALocalSource() = serverCall and
DataFlow::exprNode(any(True trueExpr))
.(DataFlow::LocalSourceNode)
.flowsTo([serverCall.getArg(2), serverCall.getArgByName("use_ssl")])
)
}
}

/**
Expand Down
Loading