mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #20983 from smowton/smowton/feature/csharp-csrf-aspnetcore
C# CSRF query: add support for ASP.NET Core
This commit is contained in:
@@ -15,6 +15,7 @@ import csharp
|
|||||||
import semmle.code.csharp.frameworks.system.Web
|
import semmle.code.csharp.frameworks.system.Web
|
||||||
import semmle.code.csharp.frameworks.system.web.Helpers
|
import semmle.code.csharp.frameworks.system.web.Helpers
|
||||||
import semmle.code.csharp.frameworks.system.web.Mvc
|
import semmle.code.csharp.frameworks.system.web.Mvc
|
||||||
|
import semmle.code.csharp.frameworks.microsoft.AspNetCore as AspNetCore
|
||||||
|
|
||||||
private Method getAValidatingMethod() {
|
private Method getAValidatingMethod() {
|
||||||
result = any(AntiForgeryClass a).getValidateMethod()
|
result = any(AntiForgeryClass a).getValidateMethod()
|
||||||
@@ -35,6 +36,8 @@ private Method getAStartedMethod() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the project has a global anti forgery filter.
|
* Holds if the project has a global anti forgery filter.
|
||||||
|
*
|
||||||
|
* No AspNetCore case here as the corresponding class doesn't seem to exist.
|
||||||
*/
|
*/
|
||||||
predicate hasGlobalAntiForgeryFilter() {
|
predicate hasGlobalAntiForgeryFilter() {
|
||||||
// A global filter added
|
// A global filter added
|
||||||
@@ -48,16 +51,30 @@ predicate hasGlobalAntiForgeryFilter() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
from Controller c, Method postMethod
|
predicate isUnvalidatedPostMethod(Class c, Method m) {
|
||||||
|
c.(Controller).getAPostActionMethod() = m and
|
||||||
|
not m.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute and
|
||||||
|
not c.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute
|
||||||
|
or
|
||||||
|
c.(AspNetCore::MicrosoftAspNetCoreMvcController).getAnActionMethod() = m and
|
||||||
|
m.getAnAttribute() instanceof AspNetCore::MicrosoftAspNetCoreMvcHttpPostAttribute and
|
||||||
|
not m.getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute and
|
||||||
|
not c.getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
Element getAValidatedElement() {
|
||||||
|
any(ValidateAntiForgeryTokenAttribute a).getTarget() = result
|
||||||
|
or
|
||||||
|
any(AspNetCore::ValidateAntiForgeryAttribute a).getTarget() = result
|
||||||
|
}
|
||||||
|
|
||||||
|
from Class c, Method postMethod
|
||||||
where
|
where
|
||||||
postMethod = c.getAPostActionMethod() and
|
isUnvalidatedPostMethod(c, postMethod) and
|
||||||
// The method is not protected by a validate anti forgery token attribute
|
|
||||||
not postMethod.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute and
|
|
||||||
not c.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute and
|
|
||||||
// Verify that validate anti forgery token attributes are used somewhere within this project, to
|
// Verify that validate anti forgery token attributes are used somewhere within this project, to
|
||||||
// avoid reporting false positives on projects that use an alternative approach to mitigate CSRF
|
// avoid reporting false positives on projects that use an alternative approach to mitigate CSRF
|
||||||
// issues.
|
// issues.
|
||||||
exists(ValidateAntiForgeryTokenAttribute a, Element e | e = a.getTarget()) and
|
exists(getAValidatedElement()) and
|
||||||
// Also ignore cases where a global anti forgery filter is in use.
|
// Also ignore cases where a global anti forgery filter is in use.
|
||||||
not hasGlobalAntiForgeryFilter()
|
not hasGlobalAntiForgeryFilter()
|
||||||
select postMethod,
|
select postMethod,
|
||||||
|
|||||||
4
csharp/ql/src/change-notes/2025-12-08-csrf-aspnetcore.md
Normal file
4
csharp/ql/src/change-notes/2025-12-08-csrf-aspnetcore.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The `Missing cross-site request forgery token validation` query was extended to support ASP.NET Core.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
// BAD: Anti forgery token has been forgotten
|
||||||
|
[HttpPost]
|
||||||
|
public ActionResult Login()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GOOD: Anti forgery token is validated
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public ActionResult UpdateDetails()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
// No validation required, as this is a GET method.
|
||||||
|
public ActionResult ShowHelp()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be ignored, because it is not an action method
|
||||||
|
[NonAction]
|
||||||
|
public void UtilityMethod()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
| MissingAntiForgeryTokenValidation.cs:7:25:7:29 | Login | Method 'Login' handles a POST request without performing CSRF token validation. |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
query: Security Features/CWE-352/MissingAntiForgeryTokenValidation.ql
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
semmle-extractor-options: /nostdlib /noconfig
|
||||||
|
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
|
||||||
Reference in New Issue
Block a user