@@ -8,80 +8,42 @@ import semmle.python.dataflow.new.DataFlow
8
8
import semmle.python.dataflow.new.TaintTracking
9
9
import semmle.python.dataflow.new.RemoteFlowSources
10
10
11
- /**
12
- * A taint-tracking configuration for detecting LDAP injections.
13
- */
14
- class LDAPInjectionFlowConfig extends TaintTracking:: Configuration {
15
- LDAPInjectionFlowConfig ( ) { this = "LDAPInjectionFlowConfig" }
11
+ module LdapInjection {
12
+ import LdapInjectionCustomizations:: LdapInjection
16
13
17
- override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowState state ) {
18
- source instanceof RemoteFlowSource and
19
- state instanceof Unsafe
20
- }
14
+ class DnConfiguration extends TaintTracking:: Configuration {
15
+ DnConfiguration ( ) { this = "LdapDnInjection" }
21
16
22
- override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowState state ) {
23
- sink = any ( LdapExecution ldap ) .getBaseDn ( ) and
24
- ( state instanceof Unsafe or state instanceof UnsafeForDn )
25
- or
26
- sink = any ( LdapExecution ldap ) .getFilter ( ) and
27
- ( state instanceof Unsafe or state instanceof UnsafeForFilter )
28
- }
17
+ override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
29
18
30
- override predicate isBarrier ( DataFlow:: Node node , DataFlow:: FlowState state ) {
31
- // All additional flow steps signify a state change.
32
- // (n, `state`) --> (`node`, s)
33
- // Thus, if a node in `state` transitions to `node` and a new state,
34
- // then `state` should be blocked at `node`.
35
- isAdditionalFlowStep ( _, state , node , _)
36
- }
19
+ override predicate isSink ( DataFlow:: Node sink ) { sink instanceof DnSink }
37
20
38
- override predicate isAdditionalFlowStep (
39
- DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
40
- DataFlow:: FlowState state2
41
- ) {
42
- exists ( LdapDnEscaping ldapDnEsc |
43
- node1 = ldapDnEsc .getAnInput ( ) and
44
- node2 = ldapDnEsc .getOutput ( )
45
- |
46
- state1 instanceof Unsafe and
47
- state2 instanceof UnsafeForFilter
48
- or
49
- state1 instanceof UnsafeForDn and
50
- state2 instanceof Safe
51
- )
52
- or
53
- exists ( LdapFilterEscaping ldapFilterEsc |
54
- node1 = ldapFilterEsc .getAnInput ( ) and
55
- node2 = ldapFilterEsc .getOutput ( )
56
- |
57
- state1 instanceof Unsafe and
58
- state2 instanceof UnsafeForDn
59
- or
60
- state1 instanceof UnsafeForFilter and
61
- state2 instanceof Safe
62
- )
21
+ override predicate isSanitizer ( DataFlow:: Node node ) { node instanceof DnSanitizer }
22
+
23
+ override predicate isSanitizerGuard ( DataFlow:: BarrierGuard guard ) {
24
+ guard instanceof DnSanitizerGuard
25
+ }
63
26
}
64
- }
65
27
66
- /** A flow satte signifying generally unsafe input. */
67
- class Unsafe extends DataFlow:: FlowState {
68
- Unsafe ( ) { this = "Unsafe" }
69
- }
28
+ class FilterConfiguration extends TaintTracking:: Configuration {
29
+ FilterConfiguration ( ) { this = "LdapFilterInjection" }
70
30
71
- /** A flow state signifying input that is only unsafe for DNs. */
72
- class UnsafeForDn extends DataFlow:: FlowState {
73
- UnsafeForDn ( ) { this = "UnsafeForDn" }
74
- }
31
+ override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
75
32
76
- /** A flow state signifying input that is only unsafe for filter strings. */
77
- class UnsafeForFilter extends DataFlow:: FlowState {
78
- UnsafeForFilter ( ) { this = "UnsafeForFilter" }
79
- }
33
+ override predicate isSink ( DataFlow:: Node sink ) { sink instanceof FilterSink }
80
34
81
- /**
82
- * A flow state that signifies safe input.
83
- * Including this makes `isAdditionalFlowStep` and `isBarrier` simpler.
84
- */
85
- class Safe extends DataFlow:: FlowState {
86
- Safe ( ) { this = "Safe" }
35
+ override predicate isSanitizer ( DataFlow:: Node node ) { node instanceof FilterSanitizer }
36
+
37
+ override predicate isSanitizerGuard ( DataFlow:: BarrierGuard guard ) {
38
+ guard instanceof FilterSanitizerGuard
39
+ }
40
+ }
41
+
42
+ import DataFlow:: PathGraph
43
+
44
+ predicate ldapInjection ( DataFlow:: PathNode source , DataFlow:: PathNode sink ) {
45
+ any ( DnConfiguration dnConfig ) .hasFlowPath ( source , sink )
46
+ or
47
+ any ( FilterConfiguration filterConfig ) .hasFlowPath ( source , sink )
48
+ }
87
49
}
0 commit comments