AI Skill Report Card
Securing Dotnet Applications
Securing .NET Applications
Quick Start
CSHARP// Secure API controller example [ApiController] [Route("api/[controller]")] [Authorize(Policy = "RequireValidatedUser")] public class UserController : ControllerBase { private readonly IUserService _userService; [HttpGet("{id:int}")] [ValidateAntiForgeryToken] public async Task<IActionResult> GetUser(int id) { if (id <= 0) return BadRequest(); var user = await _userService.GetUserByIdAsync(id); return user != null ? Ok(user) : NotFound(); } }
Recommendation▾
Add specific input/output examples showing vulnerable vs secure code patterns with actual payloads (e.g., show the SQL injection string that would fail vs succeed)
Workflow
Security Review Checklist
Progress:
- Authentication & Authorization implementation
- Input validation and sanitization
- SQL injection prevention
- CSRF protection implementation
- HTTPS/TLS configuration
- Secret management review
- Error handling and logging
- Rate limiting configuration
- Security headers implementation
- Cryptographic practices audit
1. Authentication & Authorization Setup
CSHARP// Program.cs - Secure configuration builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.Zero }; }); builder.Services.AddAuthorization(options => { options.AddPolicy("RequireValidatedUser", policy => policy.RequireClaim("email_verified", "true")); });
2. Secure Data Access
CSHARP// Entity Framework - Parameterized queries public async Task<User> GetUserByEmailAsync(string email) { return await _context.Users .FromSqlRaw("SELECT * FROM Users WHERE Email = {0}", email) .FirstOrDefaultAsync(); } // ADO.NET - Explicit parameter types using var command = new SqlCommand("SELECT * FROM Users WHERE Id = @id", connection); command.Parameters.Add("@id", SqlDbType.Int).Value = userId;
3. Security Middleware Configuration
CSHARP// Security headers and HTTPS app.UseHsts(); app.UseHttpsRedirection(); app.Use(async (context, next) => { context.Response.Headers.Add("X-Content-Type-Options", "nosniff"); context.Response.Headers.Add("X-Frame-Options", "DENY"); context.Response.Headers.Add("X-XSS-Protection", "1; mode=block"); await next(); }); app.UseRateLimiter(); app.UseAuthentication(); app.UseAuthorization();
Recommendation▾
Include concrete configuration examples for appsettings.json showing secure vs insecure settings side-by-side
Examples
Example 1: SQL Injection Prevention Input: User search with potential injection
CSHARP// VULNERABLE string query = $"SELECT * FROM Users WHERE Name = '{userInput}'"; // SECURE var users = await _context.Users .Where(u => u.Name.Contains(userInput)) .ToListAsync();
Example 2: Secure Password Handling Input: User registration with password
CSHARPpublic class UserService { public async Task<bool> CreateUserAsync(string email, string password) { var hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, 12); var user = new User { Email = email, PasswordHash = hashedPassword }; _context.Users.Add(user); return await _context.SaveChangesAsync() > 0; } }
Example 3: Rate Limiting Configuration
CSHARPbuilder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter("AuthPolicy", opt => { opt.PermitLimit = 5; opt.Window = TimeSpan.FromMinutes(1); opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; }); }); [EnableRateLimiting("AuthPolicy")] [HttpPost("login")] public async Task<IActionResult> Login(LoginRequest request) { }
Recommendation▾
Add a troubleshooting section with common security misconfigurations and their fixes (e.g., 'If getting 401 errors, check token validation parameters')
Best Practices
- Database Security: Use Entity Framework parameterized queries, never string concatenation
- Rate Limiting: Implement with AspNetCoreRateLimit or built-in middleware for API protection
- Secret Management: Store in Azure Key Vault (production) or dotnet user-secrets (development)
- HTTPS Enforcement: Enable HTTPS redirects and HSTS headers in all environments
- Authorization: Use specific [Authorize] policies, avoid global authorization
- CSRF Protection: Implement [ValidateAntiForgeryToken] on state-changing operations
- Logging: Log security events but exclude sensitive data (passwords, tokens, PII)
- Memory Security: Use SecureString for sensitive data when possible
- Input Validation: Always validate on server-side regardless of client-side validation
- Error Handling: Implement custom error pages, never expose stack traces in production
Common Pitfalls
- Client-Side Trust: Never rely solely on client-side validation - always validate server-side
- Parameter Binding: Don't use AddWithValue() blindly - specify SqlDbType explicitly
- Exception Handling: Don't catch generic exceptions without proper logging
- Configuration: Don't store connection strings in appsettings.json for production
- Cryptography: Avoid deprecated APIs (MD5, SHA1, DES) - use SHA256+ and AES
- Error Exposure: Don't expose detailed error information to end users
- Anonymous Access: Don't use [AllowAnonymous] without security review
- Header Trust: Don't trust HTTP headers (X-Forwarded-For, Referer) for security decisions
- Session Management: Don't store sensitive data in client-side storage
- API Design: Don't expose internal object structure through APIs