Skip to content

Commit e93f318

Browse files
Add missing function level access control query
1 parent 354ebc2 commit e93f318

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/** Definitions for the missing function level access control query */
2+
3+
import csharp
4+
import semmle.code.csharp.frameworks.microsoft.AspNetCore
5+
import semmle.code.csharp.frameworks.system.web.UI
6+
7+
/** Holds if `m` is a method representing an action whose name indicates that it should have some authorization/authentication check. */
8+
predicate needsAuth(Method m) {
9+
(
10+
m = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod()
11+
or
12+
m.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and
13+
m.getAParameter().getType().getName().matches("%EventArgs")
14+
) and
15+
exists(string name |
16+
name =
17+
[
18+
m.getName(), m.getDeclaringType().getBaseClass*().getName(),
19+
m.getDeclaringType().getFile().getRelativePath()
20+
] and
21+
name.toLowerCase().regexpMatch(".*(edit|delete|modify|admin|superuser).*")
22+
)
23+
}
24+
25+
/** An expression that indicates that some authorization/authentication check is being performed. */
26+
class AuthExpr extends Expr {
27+
AuthExpr() {
28+
this.(MethodCall)
29+
.getTarget()
30+
.hasQualifiedName("System.Security.Principal", "IPrincipal", "IsInRole")
31+
or
32+
this.(PropertyAccess)
33+
.getTarget()
34+
.hasQualifiedName("System.Security.Principal", "IIdentity", ["IsAuthenticated", "Name"])
35+
or
36+
this.(MethodCall).getTarget().getName().toLowerCase().matches("%auth%")
37+
or
38+
this.(PropertyAccess).getTarget().getName().toLowerCase().matches("%auth%")
39+
}
40+
}
41+
42+
/** Holds if `m` is a method that should have an auth check, and does indeed have one. */
43+
predicate hasAuth(Method m) {
44+
needsAuth(m) and
45+
exists(Method om, Callable caller, AuthExpr auth |
46+
om = m
47+
or
48+
om.getDeclaringType() = m.getDeclaringType() and
49+
om.getName() = "Page_Load"
50+
|
51+
om.calls*(caller) and
52+
auth.getEnclosingCallable() = caller
53+
)
54+
}
55+
56+
/** Holds if `m` is a method that should have an auth check, but is missing it. */
57+
predicate missingAuth(Method m) {
58+
needsAuth(m) and
59+
not hasAuth(m)
60+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @name Missing function level access control
3+
* @description ... TODO
4+
* @kind problem
5+
* @problem.severity warning
6+
* @security-severity 7.5
7+
* @precision medium
8+
* @id cs/web/missing-function-level-access-control
9+
* @tags security
10+
* external/cwe/cwe-285
11+
*/
12+
13+
import csharp
14+
import semmle.code.csharp.security.auth.MissingFunctionLevelAccessControlQuery
15+
16+
from Method m
17+
where missingAuth(m)
18+
select m, "This action is missing an authorization check."

0 commit comments

Comments
 (0)