Cross-site scripting (XSS) attacks are a significant security threat where malicious scripts are injected into web pages viewed by other users. This article demonstrates building a simple blog application in ASP.NET Core MVC while preventing XSS attacks using built-in security features and best practices.
Step 1. Create the ASP.NET Core MVC Project
Create a new ASP.NET Core MVC project
dotnet new mvc -n BlogApp
cd BlogApp
Add Entity Framework Core Packages
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.Security.Application
Step 2. Set Up Entity Framework Core
Create the database context and models
Create a Data folder and add ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using XSSAttackInAspNetCoreMVC.Model;
namespace XSSAttackInAspNetCoreMVC.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
public DbSet<BlogPost> BlogPosts { get; set; }
}
}
Configure the Database Context in Startup.cs
using Microsoft.EntityFrameworkCore;
using XSSAttackInAspNetCoreMVC.Data;
namespace XSSAttackInAspNetCoreMVC
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.UseEndpoints(routes =>
{
routes.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
app.Run();
}
}
}
Add Connection String in appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=BlogAppDb;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Create the Initial Migration and Update the Database
dotnet ef migrations add InitialCreate
dotnet ef database update
Step 3. Create Controllers and Views
Create the BlogPost Model
Create a Models folder and add BlogPost.cs
using System.ComponentModel.DataAnnotations;
namespace XSSAttackInAspNetCoreMVC.Model
{
public class BlogPost
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string? Title { get; set; }
[Required]
public string? Content { get; set; }
public DateTime Created { get; set; }
}
}
Create the BlogController
Create a Controllers folder and add BlogController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Security.Application;
using XSSAttackInAspNetCoreMVC.Data;
using XSSAttackInAspNetCoreMVC.Model;
namespace XSSAttackInAspNetCoreMVC.Controllers
{
public class BlogController : Controller
{
private readonly ApplicationDbContext _context;
public BlogController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public IActionResult Index()
{
var posts = _context.BlogPosts.ToList();
return View(posts);
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(BlogPost model)
{
if (ModelState.IsValid)
{
// Sanitize inputs before saving to the database
model.Title = Sanitizer.GetSafeHtmlFragment(model.Title);
model.Content = Sanitizer.GetSafeHtmlFragment(model.Content);
_context.BlogPosts.Add(model);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View(model);
}
}
}
Create the Views
Create a Views/Blog folder and add the following views
Index.cshtml


Join the conversation! Your thoughts help the community grow.