Skip to content

Commit 7194113

Browse files
Add areas
1 parent 7691cbc commit 7194113

File tree

3 files changed

+99
-77
lines changed

3 files changed

+99
-77
lines changed

csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSFlowSteps.qll

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ private class ViewCall extends MethodCall {
5858

5959
/** Gets the name of the MVC controller that this call is made from, if any. */
6060
string getControllerName() { result + "Controller" = this.getController().getName() }
61+
62+
/** Gets the name of the Area that the controller of this call belongs to, if any. */
63+
string getAreaName() {
64+
exists(Attribute attr |
65+
attr = this.getController().getAnAttribute() and
66+
attr.getType().hasQualifiedName("Microsoft.AspNetCore.Mvc", "AreaAttribute") and
67+
result = attr.getArgument(0).(StringLiteral).getValue()
68+
)
69+
}
6170
}
6271

6372
/** A compiler-generated Razor page. */
@@ -110,17 +119,21 @@ private predicate viewCallRefersToPageRelative(ViewCall vc, RazorPage rp) {
110119

111120
/** Gets the `i`th template for view discovery. */
112121
private string getViewSearchTemplate(int i) {
113-
i = 0 and result = "/Views/{1}/{0}.cshtml"
122+
i = 0 and result = "/Areas/{2}/Views/{1}/{0}.cshtml"
123+
or
124+
i = 1 and result = "/Areas/{2}/Views/Shared/{0}.cshtml"
114125
or
115-
i = 1 and result = "/Views/Shared/{0}.cshtml"
126+
i = 2 and result = "/Views/{1}/{0}.cshtml"
116127
or
117-
i = 2 and result = getAViewSearchTemplateInCode()
128+
i = 3 and result = "/Views/Shared/{0}.cshtml"
129+
or
130+
i = 4 and result = getAViewSearchTemplateInCode()
118131
}
119132

120133
/** Gets an additional template used for view discovery defined in code. */
121134
private string getAViewSearchTemplateInCode() {
122135
exists(StringLiteral str, MethodCall addCall |
123-
addCall.getTarget().hasQualifiedName("System.Collections.Generic", "IList", "Add") and
136+
addCall.getTarget().hasName("Add") and
124137
DataFlow::localExprFlow(str, addCall.getArgument(0)) and
125138
addCall.getQualifier() = getAViewLocationList() and
126139
result = str.getValue()
@@ -134,8 +147,8 @@ private Expr getAViewLocationList() {
134147
.getProperty()
135148
.hasQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorViewEngineOptions",
136149
[
137-
"ViewLocationFormats", "PageViewLocationFormats", "AreaViewLocationFormats",
138-
"AreaPageViewLocationFormats"
150+
"ViewLocationFormats", "AreaViewLocationFormats",
151+
//"PageViewLocationFormats","AreaPageViewLocationFormats"
139152
])
140153
}
141154

@@ -145,13 +158,21 @@ private class RelativeViewCallFilepath extends NormalizableFilepath {
145158
int idx_;
146159

147160
RelativeViewCallFilepath() {
148-
exists(string template | template = getViewSearchTemplate(idx_) |
149-
this =
150-
template.replaceAll("{0}", vc_.getActionName()).replaceAll("{1}", vc_.getControllerName())
151-
or
152-
not exists(vc_.getControllerName()) and
153-
not template.matches("%{1}%") and
154-
this = template.replaceAll("{0}", vc_.getActionName())
161+
exists(string template, string sub2, string sub1, string sub0 |
162+
template = getViewSearchTemplate(idx_)
163+
|
164+
(
165+
if template.matches("%{2}%")
166+
then sub2 = template.replaceAll("{2}", vc_.getAreaName())
167+
else sub2 = template
168+
) and
169+
(
170+
if template.matches("%{1}%")
171+
then sub1 = sub2.replaceAll("{1}", vc_.getControllerName())
172+
else sub1 = sub2
173+
) and
174+
sub0 = sub1.replaceAll("{0}", vc_.getActionName()) and
175+
this = sub0
155176
)
156177
}
157178

csharp/ql/test/query-tests/Security Features/CWE-079/XSSRazorPages/Controllers/TestController.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace test;
33
using System.Net;
44
using Microsoft.AspNetCore.Mvc;
55
using Microsoft.AspNetCore.Mvc.RazorPages;
6+
using Microsoft.AspNetCore.Mvc.Razor;
67

78
public class UserData
89
{
@@ -79,12 +80,12 @@ private IActionResult helper2(UserData x) {
7980
}
8081

8182
private IActionResult test13(UserData tainted13) {
82-
// Expected to find file /Views/Other/Test13.cshtml
83+
// MISSING: Expected to find file /Views/Other/Test13.cshtml.
8384
return Helper.helper3(this, tainted13);
8485
}
8586

8687
private IActionResult test14(UserData tainted14) {
87-
// Expected to find file /Views/Shared/Test14.cshtml and NOT /Views/Test2/Test14.cshtml
88+
// MISSING: Expected to find file /Views/Shared/Test14.cshtml and NOT /Views/Test2/Test14.cshtml
8889
return Helper.helper4(this, tainted14);
8990
}
9091

@@ -101,8 +102,8 @@ public void Setup(RazorViewEngineOptions o) {
101102
o.ViewLocationFormats.Add("/Views/Custom/{1}/{0}.cshtml");
102103
}
103104

104-
private IActionResult Test15(UserData tainted14) {
105-
// Expected to find file /Views/Custom/Test3/Test15.cshtml
106-
return View(x);
105+
private IActionResult Test15(UserData tainted15) {
106+
// MISSING: Expected to find file /Views/Custom/Test3/Test15.cshtml
107+
return View(tainted15);
107108
}
108109
}

0 commit comments

Comments
 (0)