C# Security Best Practices
Protect your C# applications by following these security best practices.
Validate Input Parameters
Critical
Always validate input parameters to prevent security vulnerabilities and unexpected behavior.
Recommended Approach
// Good
public void ProcessUser(string email, int age)
{
if (string.IsNullOrWhiteSpace(email))
throw new ArgumentException("Email cannot be null or empty", nameof(email));
if (age < 0 || age > 150)
throw new ArgumentOutOfRangeException(nameof(age), "Age must be between 0 and 150");
// Process user
}
Avoid This Approach
// Bad
public void ProcessUser(string email, int age)
{
// No validation - potential security risk
var user = new User { Email = email, Age = age };
// Process user
}
Use HTTPS for Secure Communication
Critical
Ensure all data transmitted between the client and server is encrypted using HTTPS.
Recommended Approach
// Good
public void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
// Other middleware
}
Avoid This Approach
// Bad
public void Configure(IApplicationBuilder app)
{
// No HTTPS redirection
// Other middleware
}
Implement Authentication and Authorization
Critical
Use authentication and authorization to protect resources and ensure only authorized users can access them.
Recommended Approach
// Good
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = "https://your-auth-server.com";
options.Audience = "your-audience";
});
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
Avoid This Approach
// Bad
// No authentication or authorization setup
services.AddAuthorization();
Sanitize User Input
Critical
Always sanitize user input to prevent injection attacks such as SQL injection and cross-site scripting (XSS).
Recommended Approach
// Good
public void ExecuteQuery(string userInput)
{
var sanitizedInput = Sanitize(userInput);
// Use sanitizedInput in database query
}
Avoid This Approach
// Bad
public void ExecuteQuery(string userInput)
{
// Directly using userInput in database query
}
Use Secure Password Storage
Critical
Store passwords securely using strong hashing algorithms like bcrypt.
Recommended Approach
// Good
public void StorePassword(string password)
{
var hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);
// Store hashedPassword in database
}
Avoid This Approach
// Bad
public void StorePassword(string password)
{
// Storing plain text password in database
}
Regularly Update Dependencies
Important
Keep all libraries and dependencies up to date to protect against known vulnerabilities.
Recommended Approach
// Good
// Regularly check for updates and apply them
// Use tools like Dependabot or npm audit to automate this process
Avoid This Approach
// Bad
// Ignoring dependency updates
// Using outdated libraries with known vulnerabilities
Implement Rate Limiting
Important
Use rate limiting to protect your application from abuse and denial-of-service attacks.
Recommended Approach
// Good
public void Configure(IApplicationBuilder app)
{
app.UseRateLimiting();
// Other middleware
}
Avoid This Approach
// Bad
public void Configure(IApplicationBuilder app)
{
// No rate limiting
// Other middleware
}
Use Content Security Policy (CSP)
Critical
Implement CSP to prevent cross-site scripting (XSS) and other code injection attacks.
Recommended Approach
// Good
public void Configure(IApplicationBuilder app)
{
app.UseCsp(options => options
.DefaultSources(s => s.Self())
.ScriptSources(s => s.Self().CustomSources("https://trustedscripts.example.com"))
.StyleSources(s => s.Self().UnsafeInline())
);
// Other middleware
}
Avoid This Approach
// Bad
public void Configure(IApplicationBuilder app)
{
// No CSP implementation
// Other middleware
}
Secure Cookies
Important
Ensure cookies are secure by setting the Secure and HttpOnly flags.
Recommended Approach
// Good
var cookieOptions = new CookieOptions
{
Secure = true, // Ensures the cookie is sent over HTTPS only
HttpOnly = true // Prevents JavaScript access to the cookie
};
Response.Cookies.Append("SessionId", sessionId, cookieOptions);
Avoid This Approach
// Bad
var cookieOptions = new CookieOptions
{
// No Secure or HttpOnly flags
};
Response.Cookies.Append("SessionId", sessionId, cookieOptions);
Implement Security Headers
Important
Add security headers like X-Content-Type-Options, X-Frame-Options, and X-XSS-Protection to enhance security.
Recommended Approach
// Good
public void Configure(IApplicationBuilder app)
{
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();
});
// Other middleware
}
Avoid This Approach
// Bad
public void Configure(IApplicationBuilder app)
{
// No security headers
// Other middleware
}
Use Strong Encryption Algorithms
Critical
Ensure that strong encryption algorithms are used for data protection.
Recommended Approach
// Good
public void EncryptData(string data)
{
using (Aes aes = Aes.Create())
{
aes.Key = GenerateStrongKey();
// Encryption logic
}
}
Avoid This Approach
// Bad
public void EncryptData(string data)
{
using (Aes aes = Aes.Create())
{
aes.Key = GenerateWeakKey();
// Encryption logic
}
}
Implement Access Controls
Critical
Ensure that access controls are in place to restrict access to sensitive data and operations.
Recommended Approach
// Good
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
}
Avoid This Approach
// Bad
// No access control policies defined
services.AddAuthorization();
Monitor and Audit Logs
Important
Regularly monitor and audit logs to detect and respond to security incidents.
Recommended Approach
// Good
public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
app.Use(async (context, next) =>
{
logger.LogInformation("Request: {Method} {Path}", context.Request.Method, context.Request.Path);
await next();
});
// Other middleware
}
Avoid This Approach
// Bad
public void Configure(IApplicationBuilder app)
{
// No logging or monitoring
// Other middleware
}
Conduct Regular Security Testing
Critical
Perform regular security testing, including vulnerability scans and penetration testing, to identify and address security weaknesses.
Recommended Approach
// Good
// Schedule regular security assessments
// Use tools like OWASP ZAP or Nessus for automated scans
Avoid This Approach
// Bad
// No regular security testing
// Ignoring potential vulnerabilities
Educate and Train Employees
Important
Provide regular security training to employees to raise awareness and reduce the risk of human error.
Recommended Approach
// Good
// Conduct regular security workshops and training sessions
// Keep employees informed about the latest security threats
Avoid This Approach
// Bad
// No security training for employees
// Lack of awareness about security best practices