CWE-284 in Aspnet
How Cwe 284 Manifests in Aspnet
CWE-284 (Improper Access Control) in ASP.NET applications often appears through role-based access control (RBAC) failures, improper authentication checks, and controller-level authorization bypasses. In ASP.NET Web Forms and MVC applications, this vulnerability frequently manifests when developers rely on client-side controls or fail to validate user permissions on the server side.
A common pattern involves using the [Authorize] attribute without proper role specification, allowing any authenticated user to access restricted functionality. For example:
public class AdminController : Controller
{
[Authorize] // Only checks if user is authenticated, not if they're an admin
public ActionResult DeleteUser(int id)
{
var user = _userService.GetById(id);
_userService.Delete(user);
return RedirectToAction("Index");
}
}
This code allows any logged-in user to delete accounts, regardless of their actual permissions. Another frequent manifestation occurs with URL-based access control, where developers assume that if a page isn't linked from the navigation, users won't find it. Attackers can directly access URLs like /Admin/DeleteUser/123 without proper authorization checks.
ASP.NET Web API endpoints are particularly vulnerable when using the [AllowAnonymous] attribute incorrectly or when authentication middleware is misconfigured. A typical scenario:
public class OrdersController : ApiController
{
public IHttpActionResult GetOrder(int id)
{
// No authentication or authorization check
var order = _orderRepository.GetById(id);
return Ok(order);
}
}
Session fixation attacks also represent a CWE-284 variant in ASP.NET, where session IDs are not properly regenerated after authentication, allowing attackers to hijack user sessions. Additionally, improper use of Windows Authentication in intranet applications can lead to elevation of privilege when the application trusts client certificates without verification.
Aspnet-Specific Detection
Detecting CWE-284 in ASP.NET applications requires both static code analysis and dynamic testing. Using middleBrick's scanner, you can identify authorization bypass vulnerabilities by submitting your API endpoints for black-box testing. The scanner tests for common ASP.NET authorization patterns and reports findings with severity levels.
For manual detection, examine your Web.config files for authentication and authorization settings:
<system.web>
<authentication mode="Forms" />
<authorization>
<deny users="?" /> <!-- Denies anonymous users -->
</authorization>
</system.web>
Check for missing [Authorize] attributes on controller actions, especially in areas handling sensitive operations like user management, financial transactions, or administrative functions. Use tools like OWASP ZAP or Burp Suite to test for direct URL access to restricted endpoints.
middleBrick specifically scans for ASP.NET authorization bypass patterns including:
- Missing or improperly configured [Authorize] attributes
- Incorrect role-based access control implementations
- Session fixation vulnerabilities
- Direct object reference issues in ASP.NET Web API controllers
- Improper use of Windows Authentication in intranet applications
The scanner also checks for common ASP.NET-specific misconfigurations like overly permissive <location> elements in Web.config that override global authorization settings:
<location path="Admin">
<system.web>
<authorization>
<allow users="*" /> <!-- This allows anyone to access /Admin -->
</authorization>
</system.web>
</location>
Code analysis tools like SonarQube with ASP.NET plugins can also identify authorization-related code smells, such as methods that perform sensitive operations without proper access control checks.
Aspnet-Specific Remediation
Remediating CWE-284 in ASP.NET requires implementing proper authentication and authorization patterns using the framework's built-in features. Start by configuring authentication correctly in Web.config:
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="30" />
</authentication>
<authorization>
<deny users="?" /> <!-- Deny anonymous users globally -->
</authorization>
</system.web>
Use the [Authorize] attribute with specific roles or policies rather than allowing any authenticated user:
public class AdminController : Controller
{
[Authorize(Roles = "Admin,SuperAdmin")]
public ActionResult DeleteUser(int id)
{
if (!User.IsInRole("Admin") && !User.IsInRole("SuperAdmin"))
{
return new HttpStatusCodeResult(403);
}
var user = _userService.GetById(id);
if (user == null || user.Id == User.Identity.GetUserId())
{
return new HttpStatusCodeResult(404);
}
_userService.Delete(user);
return RedirectToAction("Index");
}
}
For ASP.NET Core applications, implement policy-based authorization for more granular control:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdmin", policy =>
policy.RequireRole("Admin").RequireAuthenticatedUser());
});
}
[Authorize(Policy = "RequireAdmin")]
public class AdminController : Controller
{
public IActionResult DeleteUser(int id)
{
// Only users in Admin role can access this
}
}
Implement proper session management by regenerating session IDs after authentication:
protected void Login_Click(object sender, EventArgs e)
{
if (Membership.ValidateUser(username.Text, password.Text))
{
FormsAuthentication.RedirectFromLoginPage(username.Text, false);
Session.Clear(); // Clear existing session
Session.Abandon(); // Abandon old session
SessionIDManager manager = new SessionIDManager();
manager.SaveSessionID(Context, Session.SessionID, out bool redirected, out bool cookieAdded);
}
}
Use anti-forgery tokens to prevent CSRF attacks that could exploit authorization bypass:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult DeleteUser(int id)
{
// Action implementation
}
For Web API controllers, implement proper authentication filters:
public class RequireAdminAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var isAuthorized = base.IsAuthorized(actionContext);
var user = actionContext.ControllerContext.RequestContext.Principal;
if (isAuthorized && user.IsInRole("Admin"))
{
return true;
}
return false;
}
}
[RequireAdmin]
public class AdminController : ApiController
{
public IHttpActionResult DeleteUser(int id)
{
// Only accessible by Admin users
}
}