>_ Security Rules

8 Rules. Zero False Positives.

Each rule is purpose-built for API authorization patterns. No generic scanning - just targeted detection for real security issues.

[EXPOSURE] HIGH

AP001: Unintentional Public Access

Detects endpoints that are accessible without authentication but lack an explicit [AllowAnonymous] attribute.

This forces developers to make intentional decisions about public access. Every public endpoint should have explicit documentation of its intent.

// Flagged - no explicit authorization intent
[ApiController]
public class UsersController
{
[HttpGet]
public IActionResult GetUsers() { }
}
 
// Fixed - explicit intent
[ApiController]
[AllowAnonymous] // or [Authorize]
public class UsersController
// Dangerous - anonymous write access
[AllowAnonymous]
[HttpPost]
public IActionResult CreateUser() { }
 
[AllowAnonymous]
[HttpDelete("{id}")]
public IActionResult DeleteUser() { }
[EXPOSURE] HIGH

AP002: Anonymous Write Operations

Catches [AllowAnonymous] on POST, PUT, DELETE, and PATCH operations.

Anonymous write access is almost never intentional. This rule prevents accidental exposure of data modification endpoints.

[CONSISTENCY] MEDIUM

AP003: Authorization Conflicts

Detects when action-level [AllowAnonymous] overrides controller-level [Authorize].

This pattern often indicates copy-paste errors or incomplete refactoring. It creates security holes in otherwise protected controllers.

[Authorize] // Controller is protected
public class AdminController
{
[AllowAnonymous] // Conflict!
[HttpGet("stats")]
public IActionResult GetStats() { }
}
// CRITICAL - No auth on write operation
[ApiController]
public class OrdersController
{
[HttpPost]
public IActionResult CreateOrder() { }
 
[HttpDelete("{id}")]
public IActionResult DeleteOrder() { }
}
[CONSISTENCY] CRITICAL

AP004: Missing Auth on Writes

The most critical rule: public write operations without any authorization attributes. This is your last line of defense.

Write operations (POST, PUT, DELETE, PATCH) should always have explicit authorization. No exceptions.

[PRIVILEGE] LOW

AP005: Role Sprawl

Flags endpoints with 3 or more roles assigned. This is a code smell indicating that policy-based authorization might be a better fit.

Excessive role requirements make code harder to maintain and reason about. Consider consolidating into policies.

// Role sprawl detected
[Authorize(Roles = "Admin,Manager,Supervisor,TeamLead")]
public IActionResult GetReport() { }
 
// Better - use policy
[Authorize(Policy = "CanViewReports")]
public IActionResult GetReport() { }
// Generic role names
[Authorize(Roles = "Admin")]
[Authorize(Roles = "User")]
[Authorize(Roles = "Manager")]
 
// Descriptive role names
[Authorize(Roles = "OrderManager")]
[Authorize(Roles = "ReportViewer")]
[Authorize(Roles = "InventoryAuditor")]
[PRIVILEGE] LOW

AP006: Weak Role Names

Detects generic roles like "User", "Admin", "Guest", and "Manager". These names don't convey specific permissions.

Descriptive role names like "OrderManager" or "ReportViewer" make authorization logic self-documenting.

[SURFACE] MEDIUM

AP007: Sensitive Routes Exposed

Flags public routes containing sensitive keywords like /admin, /debug, /export, /config.

The keyword list is customizable via configuration. Add your own patterns to match your application's conventions.

// Sensitive route patterns
[HttpGet("/admin/users")]
[HttpGet("/debug/logs")]
[HttpGet("/export/data")]
[HttpGet("/config/settings")]
[HttpGet("/internal/metrics")]
// Minimal API without auth
app.MapGet("/users", GetUsers);
app.MapPost("/users", CreateUser);
 
// Fixed - with RequireAuthorization
app.MapGet("/users", GetUsers)
.RequireAuthorization();
app.MapPost("/users", CreateUser)
.RequireAuthorization();
[SURFACE] HIGH

AP008: Minimal API Gaps

Detects Minimal API endpoints missing .RequireAuthorization() method chains.

Full support for modern .NET patterns including route groups and endpoint filters.

>_ Get Started

Ready to secure your API?

Install ApiPosture and run your first scan in under 60 seconds.