Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ predicate hasGlobalAntiForgeryFilter() {
predicate isUnvalidatedPostMethod(Class c, Method m) {
c.(Controller).getAPostActionMethod() = m and
not m.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute and
not c.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute
not c.getABaseType*().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
not c.getABaseType*().getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute
}

Element getAValidatedElement() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: fix
---
* The `cs/web/missing-token-validation` ("Missing cross-site request forgery token validation") query now recognizes antiforgery attributes on base controller classes, fixing false positives when `[ValidateAntiForgeryToken]` or `[AutoValidateAntiforgeryToken]` is applied to a parent class.
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title/description indicate a functional fix to the cs/web/missing-token-validation query, but the diff shown here only adds a change note. If the query update is part of this PR, please include it in the changes; otherwise the change note will be inaccurate.

Copilot uses AI. Check for mistakes.
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,34 @@ public void UtilityMethod()
{
}
}

// GOOD: Base class has AutoValidateAntiforgeryToken attribute
[AutoValidateAntiforgeryToken]
public abstract class BaseController : Controller
{
}

public class DerivedController : BaseController
{
// GOOD: Inherits antiforgery validation from base class
[HttpPost]
public ActionResult InheritedValidation()
{
return View();
}
}

// BAD: Base class without antiforgery attribute
public abstract class UnprotectedBaseController : Controller
{
}

public class DerivedUnprotectedController : UnprotectedBaseController
{
// BAD: No antiforgery validation on this or any base class
[HttpPost]
public ActionResult NoInheritedValidation()
{
return View();
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
| MissingAntiForgeryTokenValidation.cs:7:25:7:29 | Login | Method 'Login' handles a POST request without performing CSRF token validation. |
| MissingAntiForgeryTokenValidation.cs:47:25:47:47 | NoInheritedValidation | Method 'NoInheritedValidation' handles a POST request without performing CSRF token validation. |
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,34 @@ public void UtilityMethod()
{
}
}

// GOOD: Base class has ValidateAntiForgeryToken attribute
[ValidateAntiForgeryToken]
public abstract class BaseController : Controller
{
}

public class DerivedController : BaseController
{
// GOOD: Inherits antiforgery validation from base class
[HttpPost]
public ActionResult InheritedValidation()
{
return View();
}
}

// BAD: Base class without antiforgery attribute
public abstract class UnprotectedBaseController : Controller
{
}

public class DerivedUnprotectedController : UnprotectedBaseController
{
// BAD: No antiforgery validation on this or any base class
[HttpPost]
public ActionResult NoInheritedValidation()
{
return View();
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
| MissingAntiForgeryTokenValidation.cs:7:25:7:29 | Login | Method 'Login' handles a POST request without performing CSRF token validation. |
| MissingAntiForgeryTokenValidation.cs:47:25:47:47 | NoInheritedValidation | Method 'NoInheritedValidation' handles a POST request without performing CSRF token validation. |
Loading