2
2
3
3
import csharp
4
4
import semmle.code.csharp.dataflow.flowsources.Remote
5
+ import DataFlow as DF
5
6
import TaintTracking as TT
6
7
import ActionMethods
7
8
@@ -25,20 +26,30 @@ private predicate hasIdParameter(ActionMethod m) {
25
26
exists ( StringLiteral idStr , IndexerCall idx |
26
27
idStr .getValue ( ) .toLowerCase ( ) .matches ( [ "%id" , "%idx" ] ) and
27
28
TT:: localTaint ( src , DataFlow:: exprNode ( idx .getQualifier ( ) ) ) and
28
- idStr = idx .getArgument ( 0 )
29
+ DF :: localExprFlow ( idStr , idx .getArgument ( 0 ) )
29
30
)
30
31
)
31
32
}
32
33
34
+ private predicate authorizingCallable ( Callable c ) {
35
+ exists ( string name | name = c .getName ( ) .toLowerCase ( ) |
36
+ name .matches ( [ "%user%" , "%session%" ] ) and
37
+ not name .matches ( "%get%by%" ) // methods like `getUserById` or `getXByUsername` aren't likely to be referring to the current user
38
+ )
39
+ }
40
+
33
41
/** Holds if `m` at some point in its call graph may make some kind of check against the current user. */
34
42
private predicate checksUser ( ActionMethod m ) {
35
- exists ( Callable c , string name | name = c .getName ( ) .toLowerCase ( ) |
36
- name .matches ( [ "%user%" , "%session%" ] ) and
37
- not name .matches ( "%get%by%" ) and // methods like `getUserById` or `getXByUsername` aren't likely to be referring to the current user
38
- m .calls * ( c )
43
+ exists ( Callable c |
44
+ authorizingCallable ( c ) and
45
+ callsPlus ( m , c )
39
46
)
40
47
}
41
48
49
+ private predicate calls ( Callable c1 , Callable c2 ) { c1 .calls ( c2 ) }
50
+
51
+ private predicate callsPlus ( Callable c1 , Callable c2 ) = fastTC( calls / 2 ) ( c1 , c2 )
52
+
42
53
/** Holds if `m`, its containing class, or a parent class has an attribute that extends `AuthorizeAttribute` */
43
54
private predicate hasAuthorizeAttribute ( ActionMethod m ) {
44
55
exists ( Attribute attr |
0 commit comments