@@ -4,25 +4,46 @@ import csharp
44import semmle.code.csharp.dataflow.flowsources.Remote
55import ActionMethods
66
7+ /**
8+ * Holds if `m` is a method that may require checks
9+ * against the current user to modify a particular resource.
10+ */
11+ // We exclude admin methods as it may be expected that an admin user should be able to modify any resource.
12+ // Other queries check that there are authorization checks in place for admin methods.
713private predicate needsChecks ( ActionMethod m ) { m .isEdit ( ) and not m .isAdmin ( ) }
814
15+ private Expr getParentExpr ( Expr ex ) { result = ex .getParent ( ) }
16+
17+ /**
18+ * Holds if `m` has a parameter or access a remote flow source
19+ * that may indicate that it's used as the ID for some resource
20+ */
921private predicate hasIdParameter ( ActionMethod m ) {
1022 exists ( RemoteFlowSource src | src .getEnclosingCallable ( ) = m |
11- src .asParameter ( ) .getName ( ) .toLowerCase ( ) .matches ( "%id" )
23+ src .asParameter ( ) .getName ( ) .toLowerCase ( ) .matches ( [ "%id" , "%idx" ] )
1224 or
1325 exists ( StringLiteral idStr |
14- idStr .getValue ( ) .toLowerCase ( ) .matches ( "%id" ) and
15- idStr . getParent * ( ) = src . asExpr ( )
26+ idStr .getValue ( ) .toLowerCase ( ) .matches ( [ "%id" , "%idx" ] ) and
27+ getParentExpr * ( src . asExpr ( ) ) = getParentExpr * ( idStr )
1628 )
1729 )
1830}
1931
32+ /** Holds if `m` at some point in its call graph may make some kind of check against the current user. */
2033private predicate checksUser ( ActionMethod m ) {
21- exists ( Callable c | c .getName ( ) .toLowerCase ( ) .matches ( "%user%" ) | m .calls * ( c ) )
34+ exists ( Property p | p .getName ( ) .toLowerCase ( ) .matches ( [ "%user%" , "%session%" ] ) |
35+ m .calls * ( p .getGetter ( ) )
36+ )
2237}
2338
39+ /**
40+ * Holds if `m` is a method that modifies a particular resource based on
41+ * and ID provided by user input, but does not check anything based on the current user
42+ * to determine if they should modify this resource.
43+ */
2444predicate hasInsecureDirectObjectReference ( ActionMethod m ) {
2545 needsChecks ( m ) and
2646 hasIdParameter ( m ) and
27- not checksUser ( m )
47+ not checksUser ( m ) and
48+ exists ( m .getBody ( ) )
2849}
0 commit comments