Skip to content

Commit 9153528

Browse files
Check for generic base types in Missing Function Level Access Control and Insecure Direct Object Reference.
1 parent f657071 commit 9153528

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

csharp/ql/lib/semmle/code/csharp/security/auth/InsecureDirectObjectReferenceQuery.qll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,31 +51,33 @@ private predicate callsPlus(Callable c1, Callable c2) = fastTC(calls/2)(c1, c2)
5151
/** Holds if `m`, its containing class, or a parent class has an attribute that extends `AuthorizeAttribute` */
5252
private predicate hasAuthorizeAttribute(ActionMethod m) {
5353
exists(Attribute attr |
54-
attr.getType()
55-
.getABaseType*()
54+
getAnUnboundBaseType*(attr.getType())
5655
.hasQualifiedName([
5756
"Microsoft.AspNetCore.Authorization", "System.Web.Mvc", "System.Web.Http"
5857
], "AuthorizeAttribute")
5958
|
6059
attr = m.getOverridee*().getAnAttribute() or
61-
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
60+
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
6261
)
6362
}
6463

6564
/** Holds if `m`, its containing class, or a parent class has an attribute that extends `AllowAnonymousAttribute` */
6665
private predicate hasAllowAnonymousAttribute(ActionMethod m) {
6766
exists(Attribute attr |
68-
attr.getType()
69-
.getABaseType*()
67+
getAnUnboundBaseType*(attr.getType())
7068
.hasQualifiedName([
7169
"Microsoft.AspNetCore.Authorization", "System.Web.Mvc", "System.Web.Http"
7270
], "AllowAnonymousAttribute")
7371
|
7472
attr = m.getOverridee*().getAnAttribute() or
75-
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
73+
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
7674
)
7775
}
7876

77+
private ValueOrRefType getAnUnboundBaseType(ValueOrRefType t) {
78+
result = t.getABaseType().getUnboundDeclaration()
79+
}
80+
7981
/** Holds if `m` is authorized via an `Authorize` attribute */
8082
private predicate isAuthorizedViaAttribute(ActionMethod m) {
8183
hasAuthorizeAttribute(m) and

csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,15 @@ predicate hasAuthViaXml(ActionMethod m) {
8282
/** Holds if the given action has an attribute that indications authorization. */
8383
predicate hasAuthViaAttribute(ActionMethod m) {
8484
exists(Attribute attr | attr.getType().getName().toLowerCase().matches("%auth%") |
85-
attr = m.getAnAttribute() or
86-
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
85+
attr = m.getOverridee*().getAnAttribute() or
86+
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
8787
)
8888
}
8989

90+
private ValueOrRefType getAnUnboundBaseType(ValueOrRefType t) {
91+
result = t.getABaseType().getUnboundDeclaration()
92+
}
93+
9094
/** Holds if `m` is a method that should have an auth check, but is missing it. */
9195
predicate missingAuth(ActionMethod m) {
9296
needsAuth(m) and
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `cs/web/insecure-direct-object-reference` and `cs/web/missing-function-level-access-control` have been improved to better recognize attributes on generic classes.

csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,30 @@ public ActionResult Delete3(int id) {
2727
return View();
2828
}
2929

30+
}
31+
32+
[Authorize]
33+
public class AuthBaseController : Controller {
34+
protected void doThings() { }
35+
}
36+
37+
public class SubController : AuthBaseController {
38+
// GOOD: The Authorize attribute is used on the base class.
39+
public ActionResult Delete4(int id) {
40+
doThings();
41+
return View();
42+
}
43+
}
44+
45+
[Authorize]
46+
public class AuthBaseGenericController<T> : Controller {
47+
protected void doThings() { }
48+
}
49+
50+
public class SubGenericController : AuthBaseGenericController<string> {
51+
// GOOD: The Authorize attribute is used on the base class.
52+
public ActionResult Delete5(int id) {
53+
doThings();
54+
return View();
55+
}
3056
}

csharp/ql/test/query-tests/Security Features/CWE-639/MVCTests/MiscTestControllers.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,14 @@ public class CController : BaseAnonController {
4343
// BAD - AllowAnonymous is inherited from base class and overrides Authorize
4444
[Authorize]
4545
public ActionResult Edit4(int id) { return View(); }
46+
}
47+
48+
[Authorize]
49+
public class BaseGenController<T> : Controller {
50+
51+
}
52+
53+
public class SubGenController : BaseGenController<string> {
54+
// GOOD - Authorize is inherited from parent class
55+
public ActionResult Edit5(int id) { return View(); }
4656
}

0 commit comments

Comments
 (0)