@@ -5,7 +5,12 @@ import semmle.code.csharp.frameworks.microsoft.AspNetCore
5
5
import semmle.code.csharp.frameworks.system.web.UI
6
6
import semmle.code.asp.WebConfig
7
7
8
+ /** A method representing an action for a web endpoint. */
8
9
abstract class ActionMethod extends Method {
10
+ /**
11
+ * Gets a string that can indicate what this method does to determine if it should have an auth check;
12
+ * such as its method name, class name, or file path.
13
+ */
9
14
string getADescription ( ) {
10
15
result =
11
16
[
@@ -14,23 +19,31 @@ abstract class ActionMethod extends Method {
14
19
]
15
20
}
16
21
22
+ /** Holds if this method may need an authorization check. */
17
23
predicate needsAuth ( ) {
18
24
this .getADescription ( )
19
25
.regexpReplaceAll ( "([a-z])([A-Z])" , "$1_$2" )
26
+ // separate camelCase words
20
27
.toLowerCase ( )
21
28
.regexpMatch ( ".*(edit|delete|modify|admin|superuser).*" )
22
29
}
23
30
31
+ /** Gets a callable for which if it contains an auth check, this method should be considered authenticated. */
24
32
Callable getAnAuthorizingCallable ( ) { result = this }
25
33
34
+ /**
35
+ * Gets a possible url route that could refer to this action,
36
+ * which would be covered by `<location>` configurations specifying a prefix of it.
37
+ */
26
38
string getARoute ( ) { result = this .getDeclaringType ( ) .getFile ( ) .getRelativePath ( ) }
27
39
}
28
40
41
+ /** An action method in the MVC framework. */
29
42
private class MvcActionMethod extends ActionMethod {
30
43
MvcActionMethod ( ) { this = any ( MicrosoftAspNetCoreMvcController c ) .getAnActionMethod ( ) }
31
- // override string getARoute() { none() }
32
44
}
33
45
46
+ /** An action method on a subclass of `System.Web.UI.Page`. */
34
47
private class WebFormActionMethod extends ActionMethod {
35
48
WebFormActionMethod ( ) {
36
49
this .getDeclaringType ( ) .getBaseClass * ( ) instanceof SystemWebUIPageClass and
@@ -56,6 +69,11 @@ private class WebFormActionMethod extends ActionMethod {
56
69
}
57
70
}
58
71
72
+ /**
73
+ * Holds if `virtualRoute` is a URL path
74
+ * that can map to the corresponding `physicalRoute` filepath
75
+ * through a call to `MapPageRoute`
76
+ */
59
77
private predicate virtualRouteMapping ( string virtualRoute , string physicalRoute ) {
60
78
exists ( MethodCall mapPageRouteCall , StringLiteral virtualLit , StringLiteral physicalLit |
61
79
mapPageRouteCall
@@ -69,6 +87,7 @@ private predicate virtualRouteMapping(string virtualRoute, string physicalRoute)
69
87
)
70
88
}
71
89
90
+ /** Holds if the filepath `route` can refer to `actual` after expanding a '~". */
72
91
bindingset [ route, actual]
73
92
private predicate physicalRouteMatches ( string route , string actual ) {
74
93
route = actual
@@ -103,16 +122,20 @@ predicate hasAuthViaCode(ActionMethod m) {
103
122
)
104
123
}
105
124
125
+ /** An `<authorization>` XML element that */
106
126
class AuthorizationXmlElement extends XmlElement {
107
127
AuthorizationXmlElement ( ) {
108
128
this .getParent ( ) instanceof SystemWebXmlElement and
109
129
this .getName ( ) .toLowerCase ( ) = "authorization"
110
130
}
111
131
132
+ /** Holds if this element has a `<deny>` element to deny access to a resource. */
112
133
predicate hasDenyElement ( ) { this .getAChild ( ) .getName ( ) .toLowerCase ( ) = "deny" }
113
134
135
+ /** Gets the physical filepath of this element. */
114
136
string getPhysicalPath ( ) { result = this .getFile ( ) .getParentContainer ( ) .getRelativePath ( ) }
115
137
138
+ /** Gets the path specified by a `<location>` tag containing this element, if any. */
116
139
string getLocationTagPath ( ) {
117
140
exists ( LocationXmlElement loc , XmlAttribute path |
118
141
loc = this .getParent ( ) .( SystemWebXmlElement ) .getParent ( ) and
@@ -122,6 +145,7 @@ class AuthorizationXmlElement extends XmlElement {
122
145
)
123
146
}
124
147
148
+ /** Gets a route prefix that this configuration can refer to. */
125
149
string getARoute ( ) {
126
150
result = this .getLocationTagPath ( )
127
151
or
@@ -134,7 +158,6 @@ class AuthorizationXmlElement extends XmlElement {
134
158
135
159
/**
136
160
* Holds if the given action has an xml `authorization` tag that refers to it.
137
- * TODO: Currently only supports physical paths, however virtual paths defined by `AddRoute` can also be used.
138
161
*/
139
162
predicate hasAuthViaXml ( ActionMethod m ) {
140
163
exists ( AuthorizationXmlElement el , string rest |
@@ -143,6 +166,7 @@ predicate hasAuthViaXml(ActionMethod m) {
143
166
)
144
167
}
145
168
169
+ /** Holds if the given action has an `Authorize` attribute. */
146
170
predicate hasAuthViaAttribute ( ActionMethod m ) {
147
171
[ m .getAnAttribute ( ) , m .getDeclaringType ( ) .getAnAttribute ( ) ]
148
172
.getType ( )
@@ -154,5 +178,6 @@ predicate missingAuth(ActionMethod m) {
154
178
m .needsAuth ( ) and
155
179
not hasAuthViaCode ( m ) and
156
180
not hasAuthViaXml ( m ) and
157
- not hasAuthViaAttribute ( m )
181
+ not hasAuthViaAttribute ( m ) and
182
+ exists ( m .getBody ( ) .getAChildStmt ( ) ) // exclude empty methods
158
183
}
0 commit comments