@@ -39,6 +39,36 @@ private predicate checksUser(ActionMethod m) {
3939 )
4040}
4141
42+ /** Holds if `m`, its containing class, or a parent class has an attribute that extends `AuthorizeAttribute` */
43+ private predicate hasAuthorizeAttribute ( ActionMethod m ) {
44+ exists ( Attribute attr |
45+ attr .getType ( )
46+ .getABaseType * ( )
47+ .hasQualifiedName ( "Microsoft.AspNetCore.Authorization" , "AuthorizeAttribute" )
48+ |
49+ attr = m .getAnAttribute ( ) or
50+ attr = m .getDeclaringType ( ) .getABaseType * ( ) .getAnAttribute ( )
51+ )
52+ }
53+
54+ /** Holds if `m`, its containing class, or a parent class has an attribute that extends `AllowAnonymousAttribute` */
55+ private predicate hasAllowAnonymousAttribute ( ActionMethod m ) {
56+ exists ( Attribute attr |
57+ attr .getType ( )
58+ .getABaseType * ( )
59+ .hasQualifiedName ( "Microsoft.AspNetCore.Authorization" , "AllowAnonymousAttribute" )
60+ |
61+ attr = m .getAnAttribute ( ) or
62+ attr = m .getDeclaringType ( ) .getABaseType * ( ) .getAnAttribute ( )
63+ )
64+ }
65+
66+ /** Hols if `m` is authorized via an `Authorize` attribute */
67+ private predicate isAuthorizedViaAttribute ( ActionMethod m ) {
68+ hasAuthorizeAttribute ( m ) and
69+ not hasAllowAnonymousAttribute ( m )
70+ }
71+
4272/**
4373 * Holds if `m` is a method that modifies a particular resource based on
4474 * an ID provided by user input, but does not check anything based on the current user
@@ -48,5 +78,6 @@ predicate hasInsecureDirectObjectReference(ActionMethod m) {
4878 needsChecks ( m ) and
4979 hasIdParameter ( m ) and
5080 not checksUser ( m ) and
51- exists ( m .getBody ( ) )
81+ not isAuthorizedViaAttribute ( m ) and
82+ exists ( m .getBody ( ) .getAChildStmt ( ) )
5283}
0 commit comments