mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Check for generic base types in Missing Function Level Access Control and Insecure Direct Object Reference.
This commit is contained in:
@@ -51,31 +51,33 @@ private predicate callsPlus(Callable c1, Callable c2) = fastTC(calls/2)(c1, c2)
|
||||
/** Holds if `m`, its containing class, or a parent class has an attribute that extends `AuthorizeAttribute` */
|
||||
private predicate hasAuthorizeAttribute(ActionMethod m) {
|
||||
exists(Attribute attr |
|
||||
attr.getType()
|
||||
.getABaseType*()
|
||||
getAnUnboundBaseType*(attr.getType())
|
||||
.hasQualifiedName([
|
||||
"Microsoft.AspNetCore.Authorization", "System.Web.Mvc", "System.Web.Http"
|
||||
], "AuthorizeAttribute")
|
||||
|
|
||||
attr = m.getOverridee*().getAnAttribute() or
|
||||
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
|
||||
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `m`, its containing class, or a parent class has an attribute that extends `AllowAnonymousAttribute` */
|
||||
private predicate hasAllowAnonymousAttribute(ActionMethod m) {
|
||||
exists(Attribute attr |
|
||||
attr.getType()
|
||||
.getABaseType*()
|
||||
getAnUnboundBaseType*(attr.getType())
|
||||
.hasQualifiedName([
|
||||
"Microsoft.AspNetCore.Authorization", "System.Web.Mvc", "System.Web.Http"
|
||||
], "AllowAnonymousAttribute")
|
||||
|
|
||||
attr = m.getOverridee*().getAnAttribute() or
|
||||
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
|
||||
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
|
||||
)
|
||||
}
|
||||
|
||||
private ValueOrRefType getAnUnboundBaseType(ValueOrRefType t) {
|
||||
result = t.getABaseType().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
/** Holds if `m` is authorized via an `Authorize` attribute */
|
||||
private predicate isAuthorizedViaAttribute(ActionMethod m) {
|
||||
hasAuthorizeAttribute(m) and
|
||||
|
||||
@@ -82,11 +82,15 @@ predicate hasAuthViaXml(ActionMethod m) {
|
||||
/** Holds if the given action has an attribute that indications authorization. */
|
||||
predicate hasAuthViaAttribute(ActionMethod m) {
|
||||
exists(Attribute attr | attr.getType().getName().toLowerCase().matches("%auth%") |
|
||||
attr = m.getAnAttribute() or
|
||||
attr = m.getDeclaringType().getABaseType*().getAnAttribute()
|
||||
attr = m.getOverridee*().getAnAttribute() or
|
||||
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
|
||||
)
|
||||
}
|
||||
|
||||
private ValueOrRefType getAnUnboundBaseType(ValueOrRefType t) {
|
||||
result = t.getABaseType().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
/** Holds if `m` is a method that should have an auth check, but is missing it. */
|
||||
predicate missingAuth(ActionMethod m) {
|
||||
needsAuth(m) and
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* 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.
|
||||
@@ -27,4 +27,30 @@ public class ProfileController : Controller {
|
||||
return View();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public class AuthBaseController : Controller {
|
||||
protected void doThings() { }
|
||||
}
|
||||
|
||||
public class SubController : AuthBaseController {
|
||||
// GOOD: The Authorize attribute is used on the base class.
|
||||
public ActionResult Delete4(int id) {
|
||||
doThings();
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public class AuthBaseGenericController<T> : Controller {
|
||||
protected void doThings() { }
|
||||
}
|
||||
|
||||
public class SubGenericController : AuthBaseGenericController<string> {
|
||||
// GOOD: The Authorize attribute is used on the base class.
|
||||
public ActionResult Delete5(int id) {
|
||||
doThings();
|
||||
return View();
|
||||
}
|
||||
}
|
||||
@@ -43,4 +43,14 @@ public class CController : BaseAnonController {
|
||||
// BAD - AllowAnonymous is inherited from base class and overrides Authorize
|
||||
[Authorize]
|
||||
public ActionResult Edit4(int id) { return View(); }
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public class BaseGenController<T> : Controller {
|
||||
|
||||
}
|
||||
|
||||
public class SubGenController : BaseGenController<string> {
|
||||
// GOOD - Authorize is inherited from parent class
|
||||
public ActionResult Edit5(int id) { return View(); }
|
||||
}
|
||||
Reference in New Issue
Block a user