1111 */
1212
1313import csharp
14- import DataFlow
14+ import Flow :: PathGraph
1515
16- query predicate nodes = PathGraph:: nodes / 3 ;
17-
18- query predicate edges ( DataFlow:: PathNode a , DataFlow:: PathNode b ) {
19- PathGraph:: edges ( a , b )
16+ query predicate edges ( Flow:: PathNode a , Flow:: PathNode b ) {
17+ Flow:: PathGraph:: edges ( a , b )
2018 or
21- exists (
22- FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable conf1 ,
23- FlowsFromTimeSpanArithmeticToTimeComparisonCallable conf2
24- |
25- conf1 = a .getConfiguration ( ) and
26- conf1 .isSink ( a .getNode ( ) ) and
27- conf2 = b .getConfiguration ( ) and
28- b .isSource ( )
29- )
19+ FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallableConfig:: isSink ( a .getNode ( ) ) and
20+ FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig:: isSource ( b .getNode ( ) )
3021 or
31- exists (
32- FlowsFromTimeSpanArithmeticToTimeComparisonCallable conf1 ,
33- FlowsFromTimeComparisonCallableToSelectionStatementCondition conf2
34- |
35- conf1 = a .getConfiguration ( ) and
36- conf1 .isSink ( a .getNode ( ) ) and
37- conf2 = b .getConfiguration ( ) and
38- b .isSource ( )
39- )
22+ FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig:: isSink ( a .getNode ( ) ) and
23+ FlowsFromTimeComparisonCallableToSelectionStatementConditionConfig:: isSource ( b .getNode ( ) )
4024}
4125
4226/**
@@ -78,22 +62,19 @@ class DateTimeStruct extends Struct {
7862}
7963
8064/**
81- * Dataflow configuration to find flow from a GetLastWriteTime source to a DateTime arithmetic operation
65+ * Configuration to find flow from a GetLastWriteTime source to a DateTime arithmetic operation
8266 */
83- private class FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable extends TaintTracking:: Configuration
67+ private module FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallableConfig implements
68+ DataFlow:: ConfigSig
8469{
85- FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable ( ) {
86- this = "FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable"
87- }
88-
89- override predicate isSource ( DataFlow:: Node source ) {
70+ predicate isSource ( DataFlow:: Node source ) {
9071 exists ( Call call , GetLastWriteTimeMethod m |
9172 m .getACall ( ) = call and
9273 source .asExpr ( ) = call
9374 )
9475 }
9576
96- override predicate isSink ( DataFlow:: Node sink ) {
77+ predicate isSink ( DataFlow:: Node sink ) {
9778 exists ( Call call , DateTimeStruct dateTime |
9879 call .getAChild * ( ) = sink .asExpr ( ) and
9980 call = dateTime .getATimeSpanArithmeticCallable ( ) .getACall ( )
@@ -102,21 +83,24 @@ private class FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable extend
10283}
10384
10485/**
105- * Dataflow configuration to find flow from a DateTime arithmetic operation to a DateTime comparison operation
86+ * Tainttracking module to find flow from a GetLastWriteTime source to a DateTime arithmetic operation
10687 */
107- private class FlowsFromTimeSpanArithmeticToTimeComparisonCallable extends TaintTracking:: Configuration
108- {
109- FlowsFromTimeSpanArithmeticToTimeComparisonCallable ( ) {
110- this = "FlowsFromTimeSpanArithmeticToTimeComparisonCallable"
111- }
88+ private module FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable =
89+ TaintTracking:: Global< FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallableConfig > ;
11290
113- override predicate isSource ( DataFlow:: Node source ) {
91+ /**
92+ * Configuration to find flow from a DateTime arithmetic operation to a DateTime comparison operation
93+ */
94+ private module FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig implements
95+ DataFlow:: ConfigSig
96+ {
97+ predicate isSource ( DataFlow:: Node source ) {
11498 exists ( DateTimeStruct dateTime , Call call | source .asExpr ( ) = call |
11599 call = dateTime .getATimeSpanArithmeticCallable ( ) .getACall ( )
116100 )
117101 }
118102
119- override predicate isSink ( DataFlow:: Node sink ) {
103+ predicate isSink ( DataFlow:: Node sink ) {
120104 exists ( Call call , DateTimeStruct dateTime |
121105 call .getAnArgument ( ) .getAChild * ( ) = sink .asExpr ( ) and
122106 call = dateTime .getAComparisonCallable ( ) .getACall ( )
@@ -125,53 +109,69 @@ private class FlowsFromTimeSpanArithmeticToTimeComparisonCallable extends TaintT
125109}
126110
127111/**
128- * Dataflow configuration to find flow from a DateTime comparison operation to a Selection Statement (such as an If)
112+ * Tainttracking module to find flow from a DateTime arithmetic operation to a DateTime comparison operation
129113 */
130- private class FlowsFromTimeComparisonCallableToSelectionStatementCondition extends TaintTracking:: Configuration
131- {
132- FlowsFromTimeComparisonCallableToSelectionStatementCondition ( ) {
133- this = "FlowsFromTimeComparisonCallableToSelectionStatementCondition"
134- }
114+ private module FlowsFromTimeSpanArithmeticToTimeComparisonCallable =
115+ TaintTracking:: Global< FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig > ;
135116
136- override predicate isSource ( DataFlow:: Node source ) {
117+ /**
118+ * Configuration to find flow from a DateTime comparison operation to a Selection Statement (such as an If)
119+ */
120+ private module FlowsFromTimeComparisonCallableToSelectionStatementConditionConfig implements
121+ DataFlow:: ConfigSig
122+ {
123+ predicate isSource ( DataFlow:: Node source ) {
137124 exists ( DateTimeStruct dateTime , Call call | source .asExpr ( ) = call |
138125 call = dateTime .getAComparisonCallable ( ) .getACall ( )
139126 )
140127 }
141128
142- override predicate isSink ( DataFlow:: Node sink ) {
129+ predicate isSink ( DataFlow:: Node sink ) {
143130 exists ( SelectionStmt sel | sel .getCondition ( ) .getAChild * ( ) = sink .asExpr ( ) )
144131 }
145132}
146133
134+ /**
135+ * Tainttracking module to find flow from a DateTime comparison operation to a Selection Statement (such as an If)
136+ */
137+ private module FlowsFromTimeComparisonCallableToSelectionStatementCondition =
138+ TaintTracking:: Global< FlowsFromTimeComparisonCallableToSelectionStatementConditionConfig > ;
139+
140+ private module Flow =
141+ DataFlow:: MergePathGraph3< FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable:: PathNode ,
142+ FlowsFromTimeSpanArithmeticToTimeComparisonCallable:: PathNode ,
143+ FlowsFromTimeComparisonCallableToSelectionStatementCondition:: PathNode ,
144+ FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable:: PathGraph ,
145+ FlowsFromTimeSpanArithmeticToTimeComparisonCallable:: PathGraph ,
146+ FlowsFromTimeComparisonCallableToSelectionStatementCondition:: PathGraph > ;
147+
147148/**
148149 * Holds if the last file modification date from the call to getLastWriteTimeMethodCall will be used in a DateTime arithmetic operation timeArithmeticCall,
149150 * which is then used for a DateTime comparison timeComparisonCall and the result flows to a Selection statement which is likely a TimeBomb trigger
150151 */
151152predicate isPotentialTimeBomb (
152- DataFlow :: PathNode pathSource , DataFlow :: PathNode pathSink , Call getLastWriteTimeMethodCall ,
153+ Flow :: PathNode pathSource , Flow :: PathNode pathSink , Call getLastWriteTimeMethodCall ,
153154 Call timeArithmeticCall , Call timeComparisonCall , SelectionStmt selStatement
154155) {
155- exists (
156- FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable config1 , Node sink ,
157- DateTimeStruct dateTime , FlowsFromTimeSpanArithmeticToTimeComparisonCallable config2 ,
158- Node sink2 , FlowsFromTimeComparisonCallableToSelectionStatementCondition config3 , Node sink3
159- |
160- pathSource .getNode ( ) = exprNode ( getLastWriteTimeMethodCall ) and
161- config1 .hasFlow ( exprNode ( getLastWriteTimeMethodCall ) , sink ) and
156+ exists ( DataFlow:: Node sink , DateTimeStruct dateTime , DataFlow:: Node sink2 , DataFlow:: Node sink3 |
157+ pathSource .getNode ( ) = DataFlow:: exprNode ( getLastWriteTimeMethodCall ) and
158+ FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable:: flow ( DataFlow:: exprNode ( getLastWriteTimeMethodCall ) ,
159+ sink ) and
162160 timeArithmeticCall = dateTime .getATimeSpanArithmeticCallable ( ) .getACall ( ) and
163161 timeArithmeticCall .getAChild * ( ) = sink .asExpr ( ) and
164- config2 .hasFlow ( exprNode ( timeArithmeticCall ) , sink2 ) and
162+ FlowsFromTimeSpanArithmeticToTimeComparisonCallable:: flow ( DataFlow:: exprNode ( timeArithmeticCall ) ,
163+ sink2 ) and
165164 timeComparisonCall = dateTime .getAComparisonCallable ( ) .getACall ( ) and
166165 timeComparisonCall .getAnArgument ( ) .getAChild * ( ) = sink2 .asExpr ( ) and
167- config3 .hasFlow ( exprNode ( timeComparisonCall ) , sink3 ) and
166+ FlowsFromTimeComparisonCallableToSelectionStatementCondition:: flow ( DataFlow:: exprNode ( timeComparisonCall ) ,
167+ sink3 ) and
168168 selStatement .getCondition ( ) .getAChild * ( ) = sink3 .asExpr ( ) and
169169 pathSink .getNode ( ) = sink3
170170 )
171171}
172172
173173from
174- DataFlow :: PathNode source , DataFlow :: PathNode sink , Call getLastWriteTimeMethodCall ,
174+ Flow :: PathNode source , Flow :: PathNode sink , Call getLastWriteTimeMethodCall ,
175175 Call timeArithmeticCall , Call timeComparisonCall , SelectionStmt selStatement
176176where
177177 isPotentialTimeBomb ( source , sink , getLastWriteTimeMethodCall , timeArithmeticCall ,
0 commit comments