Skip to content

Commit ce9e61d

Browse files
felickzCopilot
andcommitted
C#: Add Razor Page handler method parameters as remote flow sources
ASP.NET Core Razor Page handler method parameters (OnGet, OnPost, etc.) were not modeled as remote flow sources, causing security queries like SQL injection to miss vulnerabilities in PageModel subclasses. This adds AspNetCorePageHandlerMethodParameter, analogous to the existing AspNetCoreActionMethodParameter for MVC controllers, using the existing PageModelClass.getAHandlerMethod() from Razor.qll. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent daefaff commit ce9e61d

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private import semmle.code.csharp.frameworks.system.web.ui.WebControls
1313
private import semmle.code.csharp.frameworks.WCF
1414
private import semmle.code.csharp.frameworks.microsoft.Owin
1515
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
16+
private import semmle.code.csharp.frameworks.Razor
1617
private import semmle.code.csharp.dataflow.internal.ExternalFlow
1718
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
1819

@@ -314,6 +315,22 @@ class AspNetCoreActionMethodParameter extends AspNetCoreRemoteFlowSource, DataFl
314315
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
315316
}
316317

318+
/** A parameter to a Razor Page handler method, viewed as a source of remote user input. */
319+
class AspNetCorePageHandlerMethodParameter extends AspNetCoreRemoteFlowSource,
320+
DataFlow::ParameterNode
321+
{
322+
AspNetCorePageHandlerMethodParameter() {
323+
exists(Parameter p |
324+
p = this.getParameter() and
325+
p.fromSource()
326+
|
327+
p = any(PageModelClass pm).getAHandlerMethod().getAParameter()
328+
)
329+
}
330+
331+
override string getSourceType() { result = "ASP.NET Core Razor Page handler method parameter" }
332+
}
333+
317334
private class ExternalRemoteFlowSource extends RemoteFlowSource {
318335
ExternalRemoteFlowSource() { sourceNode(this, "remote") }
319336

csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,32 @@ public abstract class AbstractTestController : Controller
6363
{
6464
public void MyActionMethod(string param) { }
6565
}
66+
67+
// Razor Page handler tests
68+
public class MyPageModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
69+
{
70+
// BAD: handler method parameters are user-controlled
71+
public void OnGet(string id) { }
72+
73+
public void OnPost(string command, int count) { }
74+
75+
public void OnPostAsync(string data) { }
76+
77+
public void OnPut(string value) { }
78+
79+
public void OnDelete(string itemId) { }
80+
81+
// GOOD: not a handler method (doesn't start with On)
82+
public void GetUser(string userId) { }
83+
84+
// GOOD: marked with NonHandler attribute
85+
[Microsoft.AspNetCore.Mvc.RazorPages.NonHandlerAttribute]
86+
public void OnGetNonHandler(string param) { }
87+
}
88+
89+
// Subclass of a PageModel subclass
90+
public class DerivedPageModel : MyPageModel
91+
{
92+
public void OnPost(string derivedParam) { }
93+
}
6694
}

csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@ remoteFlowSources
1414
| AspRemoteFlowSource.cs:54:69:54:82 | mapDeleteParam |
1515
| AspRemoteFlowSource.cs:56:41:56:44 | item |
1616
| AspRemoteFlowSource.cs:64:43:64:47 | param |
17+
| AspRemoteFlowSource.cs:71:34:71:35 | id |
18+
| AspRemoteFlowSource.cs:73:35:73:41 | command |
19+
| AspRemoteFlowSource.cs:73:48:73:52 | count |
20+
| AspRemoteFlowSource.cs:75:40:75:43 | data |
21+
| AspRemoteFlowSource.cs:77:34:77:38 | value |
22+
| AspRemoteFlowSource.cs:79:37:79:42 | itemId |
23+
| AspRemoteFlowSource.cs:92:35:92:46 | derivedParam |

0 commit comments

Comments
 (0)