Skip to content

Commit c3cd40f

Browse files
Add flow steps from page models
1 parent 5778720 commit c3cd40f

File tree

1 file changed

+50
-0
lines changed
  • csharp/ql/lib/semmle/code/csharp/frameworks

1 file changed

+50
-0
lines changed

csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,53 @@ private class RelativeViewCallFilepath extends NormalizableFilepath {
215215
/** Holds if this string is the `idx`th path that will be searched for the `vc` call. */
216216
predicate hasViewCallWithIndex(ViewCall vc, int idx) { vc = vc_ and idx = idx_ }
217217
}
218+
219+
/** A subclass of `Microsoft.AspNetCore.Mvc.RazorPages.PageModel` */
220+
class PageModelClass extends Class {
221+
PageModelClass() {
222+
this.getABaseType+().hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.RazorPages", "PageModel")
223+
}
224+
225+
/** A handler method such as `OnGetAsync` */
226+
Method getAHandlerMethod() {
227+
result = this.getAMethod() and
228+
result.getName().matches("On%") and
229+
not exists(Attribute attr |
230+
attr = result.getAnAttribute() and
231+
attr.getType()
232+
.hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.RazorPages", "NonHandlerAttribute")
233+
)
234+
}
235+
236+
/** Gets the Razor Page that this PageModel refers to. */
237+
RazorViewClass getPage() {
238+
exists(Field modelField |
239+
modelField.hasName("Model") and
240+
modelField.getType() = this and
241+
modelField.getDeclaringType() = result
242+
)
243+
}
244+
}
245+
246+
private MethodCall getAPageCall(PageModelClass pm) {
247+
result.getEnclosingCallable() = pm.getAHandlerMethod() and
248+
result
249+
.getTarget()
250+
.hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.RazorPages", "PageModel",
251+
["Page", "RedirectToPage"])
252+
}
253+
254+
private class PageModelJumpNode extends DataFlow::NonLocalJumpNode {
255+
PageModelClass pm;
256+
257+
PageModelJumpNode() { this.asExpr() = getAPageCall(pm).getQualifier() }
258+
259+
override DataFlow::Node getAJumpSuccessor(boolean preservesValue) {
260+
preservesValue = true and
261+
exists(PropertyAccess modelProp |
262+
result.asExpr() = modelProp and
263+
modelProp.getTarget().hasName("Model") and
264+
modelProp.getEnclosingCallable().getDeclaringType() = pm.getPage()
265+
)
266+
}
267+
}

0 commit comments

Comments
 (0)