@@ -6,25 +6,13 @@ import semmle.code.java.frameworks.UnboundId
66import semmle.code.java.frameworks.SpringLdap
77import semmle.code.java.frameworks.ApacheLdap
88
9- /** Holds if the parameter of `c` at index `paramIndex` is varargs. */
10- bindingset [ paramIndex]
11- predicate isVarargs ( Callable c , int paramIndex ) {
12- c .isVarargs ( ) and paramIndex >= c .getNumberOfParameters ( ) - 1
13- }
14-
15- /** A data flow source for unvalidated user input that is used to construct LDAP queries. */
16- abstract class LdapInjectionSource extends DataFlow:: Node { }
17-
18- /** A data flow sink for unvalidated user input that is used to construct LDAP queries. */
19- abstract class LdapInjectionSink extends DataFlow:: ExprNode { }
20-
219/**
2210 * A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
2311 */
2412class LdapInjectionFlowConfig extends TaintTracking:: Configuration {
2513 LdapInjectionFlowConfig ( ) { this = "LdapInjectionFlowConfig" }
2614
27- override predicate isSource ( DataFlow:: Node source ) { source instanceof LdapInjectionSource }
15+ override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
2816
2917 override predicate isSink ( DataFlow:: Node sink ) { sink instanceof LdapInjectionSink }
3018
@@ -56,101 +44,77 @@ class LdapInjectionFlowConfig extends TaintTracking::Configuration {
5644 }
5745}
5846
59- /** A source of remote user input. */
60- class RemoteSource extends LdapInjectionSource {
61- RemoteSource ( ) { this instanceof RemoteFlowSource }
62- }
63-
64- /** A source of local user input. */
65- class LocalSource extends LdapInjectionSource {
66- LocalSource ( ) { this instanceof LocalUserInput }
67- }
68-
6947/**
7048 * JNDI sink for LDAP injection vulnerabilities, i.e. 1st (DN) or 2nd (filter) argument to
7149 * `search` method from `DirContext`.
7250 */
73- class JndiLdapInjectionSink extends LdapInjectionSink {
74- JndiLdapInjectionSink ( ) {
75- exists ( MethodAccess ma , Method m , int index |
76- ma .getMethod ( ) = m and
77- ma .getArgument ( index ) = this .getExpr ( )
78- |
79- m .getDeclaringType ( ) .getAnAncestor ( ) instanceof TypeDirContext and
80- m .hasName ( "search" ) and
81- index in [ 0 .. 1 ]
82- )
83- }
51+ predicate jndiLdapInjectionSinkMethod ( Method m , int index ) {
52+ m .getDeclaringType ( ) .getAnAncestor ( ) instanceof TypeDirContext and
53+ m .hasName ( "search" ) and
54+ index in [ 0 .. 1 ]
8455}
8556
8657/**
8758 * UnboundID sink for LDAP injection vulnerabilities,
8859 * i.e. LDAPConnection.search, LDAPConnection.asyncSearch or LDAPConnection.searchForEntry method.
8960 */
90- class UnboundIdLdapInjectionSink extends LdapInjectionSink {
91- UnboundIdLdapInjectionSink ( ) {
92- exists ( MethodAccess ma , Method m , int index , Parameter param |
93- ma .getMethod ( ) = m and
94- ma .getArgument ( index ) = this .getExpr ( ) and
95- m .getParameter ( index ) = param
96- |
97- // LDAPConnection.search, LDAPConnection.asyncSearch or LDAPConnection.searchForEntry method
98- (
99- m instanceof MethodUnboundIdLDAPConnectionSearch or
100- m instanceof MethodUnboundIdLDAPConnectionAsyncSearch or
101- m instanceof MethodUnboundIdLDAPConnectionSearchForEntry
102- ) and
103- // Parameter is not varargs
104- not isVarargs ( m , index )
105- )
106- }
61+ predicate unboundIdLdapInjectionSinkMethod ( Method m , int index ) {
62+ exists ( Parameter param | m .getParameter ( index ) = param and not param .isVarargs ( ) |
63+ m instanceof MethodUnboundIdLDAPConnectionSearch or
64+ m instanceof MethodUnboundIdLDAPConnectionAsyncSearch or
65+ m instanceof MethodUnboundIdLDAPConnectionSearchForEntry
66+ )
10767}
10868
10969/**
11070 * Spring LDAP sink for LDAP injection vulnerabilities,
11171 * i.e. LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method.
11272 */
113- class SpringLdapInjectionSink extends LdapInjectionSink {
114- SpringLdapInjectionSink ( ) {
115- exists ( MethodAccess ma , Method m , int index , RefType paramType |
116- ma .getMethod ( ) = m and
117- ma .getArgument ( index ) = this .getExpr ( ) and
118- m .getParameterType ( index ) = paramType
119- |
120- // LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method
121- (
122- m instanceof MethodSpringLdapTemplateAuthenticate or
123- m instanceof MethodSpringLdapTemplateFind or
124- m instanceof MethodSpringLdapTemplateFindOne or
125- m instanceof MethodSpringLdapTemplateSearch or
126- m instanceof MethodSpringLdapTemplateSearchForContext or
127- m instanceof MethodSpringLdapTemplateSearchForObject
128- ) and
129- (
130- // Parameter index is 1 (DN or query) or 2 (filter) if method is not authenticate
131- index in [ 0 .. 1 ] and
132- not m instanceof MethodSpringLdapTemplateAuthenticate
133- or
134- // But it's not the last parameter in case of authenticate method (last param is password)
135- index in [ 0 .. 1 ] and
136- index < m .getNumberOfParameters ( ) - 1 and
137- m instanceof MethodSpringLdapTemplateAuthenticate
138- )
139- )
140- }
73+ predicate springLdapInjectionSinkMethod ( Method m , int index ) {
74+ // LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method
75+ (
76+ m instanceof MethodSpringLdapTemplateAuthenticate or
77+ m instanceof MethodSpringLdapTemplateFind or
78+ m instanceof MethodSpringLdapTemplateFindOne or
79+ m instanceof MethodSpringLdapTemplateSearch or
80+ m instanceof MethodSpringLdapTemplateSearchForContext or
81+ m instanceof MethodSpringLdapTemplateSearchForObject
82+ ) and
83+ (
84+ // Parameter index is 1 (DN or query) or 2 (filter) if method is not authenticate
85+ index in [ 0 .. 1 ] and
86+ not m instanceof MethodSpringLdapTemplateAuthenticate
87+ or
88+ // But it's not the last parameter in case of authenticate method (last param is password)
89+ index in [ 0 .. 1 ] and
90+ index < m .getNumberOfParameters ( ) - 1 and
91+ m instanceof MethodSpringLdapTemplateAuthenticate
92+ )
14193}
14294
14395/** Apache LDAP API sink for LDAP injection vulnerabilities, i.e. LdapConnection.search method. */
144- class ApacheLdapInjectionSink extends LdapInjectionSink {
145- ApacheLdapInjectionSink ( ) {
146- exists ( MethodAccess ma , Method m , int index , RefType paramType |
96+ predicate apacheLdapInjectionSinkMethod ( Method m , int index ) {
97+ exists ( Parameter param | m .getParameter ( index ) = param and not param .isVarargs ( ) |
98+ m .getDeclaringType ( ) .getAnAncestor ( ) instanceof TypeApacheLdapConnection and
99+ m .hasName ( "search" )
100+ )
101+ }
102+
103+ /** Holds if parameter at index `index` in method `m` is LDAP injection sink. */
104+ predicate ldapInjectionSinkMethod ( Method m , int index ) {
105+ jndiLdapInjectionSinkMethod ( m , index ) or
106+ unboundIdLdapInjectionSinkMethod ( m , index ) or
107+ springLdapInjectionSinkMethod ( m , index ) or
108+ apacheLdapInjectionSinkMethod ( m , index )
109+ }
110+
111+ /** A data flow sink for unvalidated user input that is used to construct LDAP queries. */
112+ class LdapInjectionSink extends DataFlow:: ExprNode {
113+ LdapInjectionSink ( ) {
114+ exists ( MethodAccess ma , Method m , int index |
147115 ma .getMethod ( ) = m and
148116 ma .getArgument ( index ) = this .getExpr ( ) and
149- m .getParameterType ( index ) = paramType
150- |
151- m .getDeclaringType ( ) .getAnAncestor ( ) instanceof TypeApacheLdapConnection and
152- m .hasName ( "search" ) and
153- not isVarargs ( m , index )
117+ ldapInjectionSinkMethod ( m , index )
154118 )
155119 }
156120}
@@ -235,12 +199,13 @@ predicate filterToStringStep(ExprNode n1, ExprNode n2) {
235199 * `SearchRequest`, i.e. `new SearchRequest(tainted)`.
236200 */
237201predicate unboundIdSearchRequestStep ( ExprNode n1 , ExprNode n2 ) {
238- exists ( ConstructorCall cc , int index |
202+ exists ( ConstructorCall cc , int index , Parameter param |
239203 cc .getConstructedType ( ) instanceof TypeUnboundIdSearchRequest
240204 |
241205 n1 .asExpr ( ) = cc .getArgument ( index ) and
242206 n2 .asExpr ( ) = cc and
243- not isVarargs ( cc .getConstructor ( ) , index )
207+ cc .getConstructor ( ) .getParameter ( index ) = param and
208+ not param .isVarargs ( )
244209 )
245210}
246211
0 commit comments