Assuming an application is secure because it has a login screen is a fatal error. Enterprise codebases must structurally defend against the OWASP Top 10 web vulnerabilities. ASP.NET Core MVC is highly secure by default, but developer ignorance can bypass all its protections.
XSS occurs when a web application accepts input from a user (like a blog comment) and renders it on a web page without escaping it. If an attacker submits <script>stealCookies();</script>, every user viewing that comment will execute the malicious script.
The Razor view engine (@) automatically HTMLEncodes all output. It securely renders the literal string instead of executing it.
<!-- SAFE: Razor turns the < to < automatically -->
<div>@Model.UserComment</div>
<!-- DANGEROUS: Html.Raw completely bypasses XSS protection!
It forces the browser to execute raw HTML/Scripts. NEVER use this
with user-generated content. -->
<div>@Html.Raw(Model.UserComment)</div>
SQL Injection allows attackers to manipulate raw database queries. Entering ' OR 1=1; DROP TABLE Users; -- into a login box can obliterate your system.
EF Core uses Parameterized Queries exclusively. It treats user input strictly as mapped string parameters, not executable SQL syntax. As long as you use LINQ, you are immune to SQLi.
// SAFE: EF translates this to a safe Parameterized Query
var user = await _context.Users.FirstOrDefaultAsync(u => u.Email == userInput);
// EXTREMELY DANGEROUS: String Interpolation directly into raw SQL execution
_context.Database.ExecuteSqlRaw($"SELECT * FROM Users WHERE Email = '{userInput}'");
// SAFE Raw SQL (FormattableString execution creates parameters)
_context.Database.ExecuteSqlInterpolated($"SELECT * FROM Users WHERE Email = {userInput}");
If you allow the MVC Model Binder to bind HTTP POST data directly to your Entity Framework domain models, you expose properties you never intended to be modified.
public class User {
public int Id { get; set; }
public string Name { get; set; }
public bool IsAdmin { get; set; } // Attackers target this
}
// An attacker sends a POST with: "Name=John&IsAdmin=true"
public IActionResult UpdateProfile(User model) {
_db.Users.Update(model);
_db.SaveChanges(); // Attacker is now an Admin!
}
// Strip out sensitive properties entirely
public class UpdateProfileViewModel {
public string Name { get; set; }
}
public IActionResult UpdateProfile(UpdateProfileViewModel model) {
// IsAdmin cannot possibly be manipulated
var user = _db.Users.Find(id);
user.Name = model.Name;
_db.SaveChanges();
}
By default, web browsers prevent a frontend deployed at https://myapp.com from making AJAX requests to an API at https://api.mybackend.com. This prevents unauthorized domains from accessing your API logic. However, if you *own* both domains, you must deliberately configure the backend to accept requests from the frontend using CORS.
// Program.cs
builder.Services.AddCors(options =>
{
// Define a strict policy
options.AddPolicy("StrictFrontendPolicy", builder =>
{
builder.WithOrigins("https://www.mytrustedfrontend.com") // Exactly whitelist the frontend
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials(); // Allow passing authentication cookies
// NEVER USE .AllowAnyOrigin() IN PRODUCTION!
});
});
var app = builder.Build();
// Must run before Authorization but after Routing
app.UseCors("StrictFrontendPolicy");
Q: "How does ASP.NET Core Data Protection differ from just encrypting a string with AES?"
Architect Answer: "ASP.NET Core's Data Protection API (used behind the scenes to secure Session IDs and Authentication Cookies) is a comprehensive cryptographic lifecycle management system. If you just encrypt a string with AES, you have to manage where to store the master secret key, how to securely share that key across a server farm, and what happens when that key is compromised. The Data Protection API handles algorithmic agility (automatically upgrading to better algorithms as old ones weaken), key expiration (rolling keys every 90 days), and key ring storage (securely synchronizing keys across web farms via Azure Key Vault or Redis) so the developer doesn't accidentally invent brittle, flawed cryptography."