LyraLearn AI Learning Platform
Exams
← Module 7 Β· Securing Public-Sector Web Apps
🎧 Listen

OWASP for MVC Developers

The OWASP Top 10 is the industry's standing list of the web vulnerabilities that actually get exploited. The good news: ASP.NET Core MVC ships defenses for the big four β€” if you don't disable them. Most real-world .NET vulnerabilities are a developer opting out of a default. This lesson covers the four you'll be asked about in any public-sector code review.

Injection: let EF parameterize

SQL injection happens when user input is concatenated into a query string. EF Core LINQ queries (.Where(c => c.LastName == input)) are parameterized automatically β€” the input travels as data, never as SQL. The risk reappears at the escape hatches: FromSqlRaw with string interpolation, or hand-built SqlCommand text. If you must drop to raw SQL, pass parameters (FromSqlInterpolated does this correctly; $"...{input}..." inside FromSqlRaw does not). Rule: user input may appear in a parameter, never in the SQL string.

XSS: Razor encodes, Html.Raw un-encodes

Cross-site scripting is injection into HTML instead of SQL. Razor's @model.Notes output HTML-encodes by default, so a stored <script> tag renders as harmless text. The opt-out is Html.Raw() β€” treat every use as a code-review flag. Legitimate uses (rendering CMS content you control) should be rare, documented, and never fed by user input. Watch the side doors too: JavaScript string contexts (var name = '@name'; needs JS encoding, not HTML encoding) and jQuery's .html() (prefer .text() for user data). Kendo UI grids have the same knife: column templates and encoded: false bypass encoding.

CSRF: anti-forgery tokens

Cross-site request forgery tricks a logged-in user's browser into submitting your form from another site β€” the auth cookie rides along automatically. The defense is the anti-forgery token pair:

<form asp-action="Approve">       @* tag helper emits the hidden token *@

[ValidateAntiForgeryToken]        // on the POST action
public IActionResult Approve(int id) { ... }

Better than per-action attributes: register AutoValidateAntiforgeryTokenAttribute as a global filter so every unsafe verb (POST/PUT/DELETE) is validated by default and forgetting becomes impossible. Ajax posts (jQuery, Kendo) need the token added to the request data or a header β€” a small shared JS helper pays for itself.

Over-posting: bind ViewModels, never entities

If an action takes an EF entity (Edit(Candidate model)), the model binder will happily set any property a malicious client posts β€” including IsApproved or DeterminationStatus that your form never rendered. This is over-posting (mass assignment). The fix is structural, not a [Bind] attribute you'll forget: actions accept ViewModels containing only the fields the screen edits, and AutoMapper (or explicit code) copies the permitted values onto the entity. You already keep entities and ViewModels separate for design reasons; this is the security reason.

🧠 Quiz yourself on this lesson →

Ask the AI Tutor

Grounded in the course lessons β€” it cites its sources and says when it doesn't know.