Skip to content

Commit 62cb4bf

Browse files
authored
Merge pull request #19302 from michaelnebel/csharp/missing-access-control
C#: Relax condition for authorize attributes on `cs/web/missing-function-level-access-control`.
2 parents 959a79f + 0b10d34 commit 62cb4bf

File tree

5 files changed

+42
-15
lines changed

5 files changed

+42
-15
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ predicate hasAuthViaXml(ActionMethod m) {
8181

8282
/** Holds if the given action has an attribute that indications authorization. */
8383
predicate hasAuthViaAttribute(ActionMethod m) {
84-
exists(Attribute attr | attr.getType().getName().toLowerCase().matches("%auth%") |
84+
exists(Attribute attr | attr.getType().getABaseType*().getName().toLowerCase().matches("%auth%") |
8585
attr = m.getOverridee*().getAnAttribute() or
8686
attr = getAnUnboundBaseType*(m.getDeclaringType()).getAnAttribute()
8787
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved detection of authorization checks in the `cs/web/missing-function-level-access-control` query. The query now recognizes authorization attributes inherited from base classes and interfaces.
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| ProfileController.cs:9:25:9:31 | Delete1 | This action is missing an authorization check. |
1+
| ProfileController.cs:12:25:12:31 | Delete1 | This action is missing an authorization check. |
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
Security Features/CWE-285/MissingAccessControl.ql
1+
query: Security Features/CWE-285/MissingAccessControl.ql
2+
postprocess:
3+
- utils/test/PrettyPrintModels.ql
4+
- utils/test/InlineExpectationsTestQuery.ql
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
using Microsoft.AspNetCore.Mvc;
22
using Microsoft.AspNetCore.Authorization;
33

4-
public class ProfileController : Controller {
4+
public class RequirePermissionAttribute : AuthorizeAttribute { }
5+
6+
public class ProfileController : Controller
7+
{
58
private void doThings() { }
69
private bool isAuthorized() { return false; }
710

811
// BAD: This is a Delete method, but no auth is specified.
9-
public ActionResult Delete1(int id) {
12+
public ActionResult Delete1(int id) // $ Alert
13+
{
1014
doThings();
1115
return View();
1216
}
1317

1418
// GOOD: isAuthorized is checked.
15-
public ActionResult Delete2(int id) {
16-
if (!isAuthorized()) {
19+
public ActionResult Delete2(int id)
20+
{
21+
if (!isAuthorized())
22+
{
1723
return null;
1824
}
1925
doThings();
@@ -22,35 +28,49 @@ public ActionResult Delete2(int id) {
2228

2329
// GOOD: The Authorize attribute is used.
2430
[Authorize]
25-
public ActionResult Delete3(int id) {
31+
public ActionResult Delete3(int id)
32+
{
2633
doThings();
2734
return View();
2835
}
2936

37+
// GOOD: The RequirePermission attribute is used (which extends AuthorizeAttribute).
38+
[RequirePermission]
39+
public ActionResult Delete4(int id)
40+
{
41+
doThings();
42+
return View();
43+
}
3044
}
3145

3246
[Authorize]
33-
public class AuthBaseController : Controller {
47+
public class AuthBaseController : Controller
48+
{
3449
protected void doThings() { }
3550
}
3651

37-
public class SubController : AuthBaseController {
52+
public class SubController : AuthBaseController
53+
{
3854
// GOOD: The Authorize attribute is used on the base class.
39-
public ActionResult Delete4(int id) {
55+
public ActionResult Delete4(int id)
56+
{
4057
doThings();
4158
return View();
4259
}
4360
}
4461

4562
[Authorize]
46-
public class AuthBaseGenericController<T> : Controller {
63+
public class AuthBaseGenericController<T> : Controller
64+
{
4765
protected void doThings() { }
4866
}
4967

50-
public class SubGenericController : AuthBaseGenericController<string> {
68+
public class SubGenericController : AuthBaseGenericController<string>
69+
{
5170
// GOOD: The Authorize attribute is used on the base class.
52-
public ActionResult Delete5(int id) {
71+
public ActionResult Delete5(int id)
72+
{
5373
doThings();
5474
return View();
5575
}
56-
}
76+
}

0 commit comments

Comments
 (0)