Skip to content

Commit 2d88ac1

Browse files
committed
Suggested Changes
1 parent f5e17d7 commit 2d88ac1

File tree

3 files changed

+40
-17
lines changed

3 files changed

+40
-17
lines changed

ruby/ql/lib/codeql/ruby/frameworks/Ldap.qll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ module NetLdap {
1414
/**
1515
* Flow summary for `Net::LDAP.new`. This method establishes a connection to a LDAP server.
1616
*/
17-
private class LdapSummary extends SummarizedCallable {
18-
LdapSummary() { this = "Net::LDAP.new" }
17+
private class LdapConnSummary extends SummarizedCallable {
18+
LdapConnSummary() { this = "Net::LDAP.new" }
1919

2020
override MethodCall getACall() { result = any(NetLdapConnection l).asExpr().getExpr() }
2121

@@ -24,6 +24,19 @@ module NetLdap {
2424
}
2525
}
2626

27+
/**
28+
* Flow summary for `Net::LDAP.Filter`.
29+
*/
30+
private class LdapFilterSummary extends SummarizedCallable {
31+
LdapFilterSummary() { this = "Net::LDAP::Filter" }
32+
33+
override MethodCall getACall() { result = any(NetLdapFilter l).asExpr().getExpr() }
34+
35+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
36+
input = ["Argument[0]", "Argument[1]"] and output = "ReturnValue" and preservesValue = false
37+
}
38+
}
39+
2740
/** Net LDAP Api Node */
2841
private API::Node ldap() { result = API::getTopLevelMember("Net").getMember("LDAP") }
2942

ruby/ql/lib/codeql/ruby/security/LdapInjectionCustomizations.qll

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,19 @@ module LdapInjection {
2727
* Additional taint steps for "LDAP Injection" vulnerabilities.
2828
*/
2929
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
30-
filterTaintStep(nodeFrom, nodeTo)
30+
attributeArrayTaintStep(nodeFrom, nodeTo)
3131
}
3232

33-
private predicate filterTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
33+
/**
34+
* Additional taint step to handle elements inside an array,
35+
* specifically in the context of the following LDAP search function:
36+
*
37+
* ldap.search(base: "", filter: "", attributes: [name])
38+
*/
39+
private predicate attributeArrayTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
3440
exists(DataFlow::CallNode filterCall |
35-
(
36-
filterCall =
37-
API::getTopLevelMember("Net")
38-
.getMember("LDAP")
39-
.getMember("Filter")
40-
.getAMethodCall([
41-
"begins", "bineq", "contains", "ends", "eq", "equals", "ex", "ge", "le", "ne",
42-
"present"
43-
]) or
44-
filterCall.getMethodName() = "[]"
45-
) and
46-
n1 = filterCall.getArgument([0, 1]) and
41+
filterCall.getMethodName() = "[]" and
42+
n1 = filterCall.getArgument(_) and
4743
n2 = filterCall
4844
)
4945
}
@@ -72,4 +68,14 @@ module LdapInjection {
7268
private class StringConstArrayInclusionCallAsSanitizer extends Sanitizer,
7369
StringConstArrayInclusionCallBarrier
7470
{ }
71+
72+
/**
73+
* A call to `Net::LDAP::Filter.escape`, considered as a sanitizer.
74+
*/
75+
class NetLdapFilterEscapeSanitization extends Sanitizer {
76+
NetLdapFilterEscapeSanitization() {
77+
this =
78+
API::getTopLevelMember("Net").getMember("LDAP").getMember("Filter").getAMethodCall("escape")
79+
}
80+
}
7581
}

ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.expected

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ edges
44
| LdapInjection.rb:5:10:5:20 | ...[...] | LdapInjection.rb:5:5:5:6 | dc |
55
| LdapInjection.rb:9:5:9:8 | name | LdapInjection.rb:29:62:29:73 | "cn=#{...}" |
66
| LdapInjection.rb:9:5:9:8 | name | LdapInjection.rb:33:87:33:92 | call to [] |
7-
| LdapInjection.rb:9:5:9:8 | name | LdapInjection.rb:37:5:37:10 | filter |
7+
| LdapInjection.rb:9:5:9:8 | name | LdapInjection.rb:37:41:37:44 | name |
88
| LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:9:12:9:29 | ...[...] |
99
| LdapInjection.rb:9:12:9:29 | ...[...] | LdapInjection.rb:9:5:9:8 | name |
1010
| LdapInjection.rb:37:5:37:10 | filter | LdapInjection.rb:38:62:38:67 | filter |
11+
| LdapInjection.rb:37:14:37:45 | call to eq | LdapInjection.rb:37:5:37:10 | filter |
12+
| LdapInjection.rb:37:41:37:44 | name | LdapInjection.rb:37:14:37:45 | call to eq |
1113
nodes
1214
| LdapInjection.rb:5:5:5:6 | dc | semmle.label | dc |
1315
| LdapInjection.rb:5:10:5:15 | call to params | semmle.label | call to params |
@@ -19,6 +21,8 @@ nodes
1921
| LdapInjection.rb:29:62:29:73 | "cn=#{...}" | semmle.label | "cn=#{...}" |
2022
| LdapInjection.rb:33:87:33:92 | call to [] | semmle.label | call to [] |
2123
| LdapInjection.rb:37:5:37:10 | filter | semmle.label | filter |
24+
| LdapInjection.rb:37:14:37:45 | call to eq | semmle.label | call to eq |
25+
| LdapInjection.rb:37:41:37:44 | name | semmle.label | name |
2226
| LdapInjection.rb:38:62:38:67 | filter | semmle.label | filter |
2327
subpaths
2428
#select

0 commit comments

Comments
 (0)