Preventing DoS Attacks in ASP.NET Core MVC Applications

To prevent DoS (Denial of Service) attacks in an ASP.NET Core MVC application, you can implement several strategies, each addressing different aspects of potential vulnerabilities. Here are the common approaches.

1. Rate Limiting and Throttling

  • Rate limiting controls the number of requests a client can make within a specific time period, preventing malicious users from overwhelming the server.
  • You can use middleware or third-party libraries like AspNetCoreRateLimit to implement rate limiting.

Example. using AspNetCoreRateLimit

dotnet add package AspNetCoreRateLimit

Configure it in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMemoryCache();
    services.Configure<IpRateLimitOptions>(options =>
    {
        options.GeneralRules = new List<RateLimitRule>
        {
            new RateLimitRule
            {
                Endpoint = "*",
                Limit = 1000,
                Period = "5m"
            }
        };
    });
    services.AddInMemoryRateLimiting();
    services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseIpRateLimiting();
}

2. Request Size Limiting

Limit the size of requests to prevent large payloads from being used to exhaust server resources.

In Program.cs or Startup.cs

services.Configure<IISServerOptions>(options =>
{
    options.MaxRequestBodySize = 10 * 1024; // Set limit to 10KB
});

services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = 10 * 1024; // 10KB
});

3. Timeout Configuration

Set proper timeout values for requests to avoid long-running connections that could hog resources.

In Startup.cs

services.AddHttpClient("myClient")
    .SetHandlerLifetime(TimeSpan.FromMinutes(5)) // Set handler timeout
    .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10))); // Set HTTP request timeout

4. Input Validation

Properly validate user input to avoid potential DoS vulnerabilities caused by computational complexity or resource exhaustion.

  • Validate the length, type, and format of input.
  • Reject large or malformed data early in the request pipeline.

5. Captcha for Forms

Add CAPTCHAs (e.g., Google reCAPTCHA) to critical forms (login, registration, etc.) to prevent automated bots from generating large numbers of requests.

dotnet add package reCAPTCHA.AspNetCore

Configure in Startup.cs

services.AddRecaptcha(options =>
{
    options.SiteKey = "your-site-key";
    options.SecretKey = "your-secret-key";
});

6. Distributed Caching for Load Balancing

Use caching to reduce the load on your server, thus preventing resource exhaustion. You can implement caching using MemoryCache, Redis, or NCache.

Example using MemoryCache

services.AddMemoryCache();

7. Use CDN for Static Resources

Offload static resources (images, CSS, JavaScript) to a Content Delivery Network (CDN) to reduce server load.

8. Web Application Firewall (WAF)

Use a WAF to inspect and filter traffic before it reaches your application. WAFs can block suspicious IP addresses, filter out malformed requests, and provide additional security against attacks.

9. Client-Side Caching

Implement proper cache headers to reduce unnecessary server requests by allowing browsers to cache resources.

10. HTTP/2 and Keep-Alive Settings

Tune server settings to prevent resource exhaustion. Ensure HTTP/2 is enabled, which multiplexes requests, and configure Keep-Alive settings.

Example in Startup.cs

services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2); 
});

Now we will implement the complete project for this article.

Step 1. Create a New ASP.NET Core MVC Project

Create a new ASP.NET Core MVC project via the.NET CLI or Visual Studio.

dotnet new mvc -n DoSAttackPrevention
cd DoSAttackPrevention

Step 2. Install Required NuGet Packages

Install the necessary NuGet packages.

dotnet add package AspNetCoreRateLimit
dotnet add package reCAPTCHA.AspNetCore

Step 3. Configure Services in Startup.cs

Modify Startup.cs to include the middleware and services.

using AspNetCoreRateLimit;
using Microsoft.AspNetCore.HttpOverrides;
using reCAPTCHA.AspNetCore;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add MVC
        services.AddControllersWithViews();

        // Memory Cache for Rate Limiting
        services.AddMemoryCache();

        // Configure Rate Limiting Options
        services.Configure<IpRateLimitOptions>(options =>
        {
            options.GeneralRules = new List<RateLimitRule>
            {
                new RateLimitRule
                {
                    Endpoint = "*",
                    Limit = 100,
                    Period = "1m" // 100 requests per minute per IP
                }
            };
        });

        services.AddInMemoryRateLimiting();
        services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

        // Add Recaptcha Service
        services.AddRecaptcha(options =>
        {
            options.SiteKey = "your-site-key";
            options.SecretKey = "your-secret-key";
        });

        // Configure Request Size Limit
        services.Configure<IISServerOptions>(options =>
        {
            options.MaxRequestBodySize = 10 * 1024; // 10 KB
        });

        services.Configure<KestrelServerOptions>(options =>
        {
            options.Limits.MaxRequestBodySize = 10 * 1024; // 10 KB
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseIpRateLimiting(); // Apply Rate Limiting

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

Step 4. Add Rate Limiting Configuration

In the appsettings.json file, add rate-limiting options.

{
  "IpRateLimit": {
    "EnableEndpointRateLimiting": true,
    "StackBlockedRequests": false,
    "HttpStatusCode": 429,
    "RealIpHeader": "X-Real-IP",
    "ClientIdHeader": "X-ClientId",
    "GeneralRules": [
      {
        "Endpoint": "*",
        "Period": "1m",
        "Limit": 100
      }
    ]
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Step 5. Implement CAPTCHA in a Form (e.g., Login Form)

In the Login View (Views/Home/Login.cshtml), implement Google reCAPTCHA.

@using reCAPTCHA.AspNetCore
@inject IRecaptchaService _recaptcha
@{
    var recaptchaResult = await _recaptcha.Validate(Request);
}

<form asp-controller="Home" asp-action="Login" method="post">
    <div class="form-group">
        <label for="Username">Username</label>
        <input type="text" class="form-control" id="Username" name="Username" required>
    </div>
    <div class="form-group">
        <label for="Password">Password</label>
        <input type="password" class="form-control" id="Password" name="Password" required>
    </div>

    <!-- Google reCAPTCHA -->
    <div class="g-recaptcha" data-sitekey="your-site-key"></div>

    <button type="submit" class="btn btn-primary">Login</button>
</form>

@section Scripts {
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
}

Step 6. Handle CAPTCHA Validation in the Controller

In the HomeController (Controllers/HomeController.cs), validate the CAPTCHA.

using Microsoft.AspNetCore.Mvc;
using reCAPTCHA.AspNetCore;

public class HomeController : Controller
{
    private readonly IRecaptchaService _recaptcha;

    public HomeController(IRecaptchaService recaptcha)
    {
        _recaptcha = recaptcha;
    }

    [HttpPost]
    public async Task<IActionResult> Login(string username, string password)
    {
        var recaptchaResult = await _recaptcha.Validate(Request);
        if (!recaptchaResult.success)
        {
            ModelState.AddModelError(string.Empty, "CAPTCHA validation failed.");
            return View();
        }

        // Perform login logic here (e.g., validate username/password)

        return RedirectToAction("Index");
    }

    public IActionResult Index()
    {
        return View();
    }
}

Step 7. Implement Input Validation

Ensure that proper validation is applied to forms. For example, in the login form above, you can add validation attributes in the model or controller.

[Required]
[MaxLength(50)]
public string Username { get; set; }
[Required]
[MinLength(6)]
public string Password { get; set; }

Step 8. Configure Caching (Optional)

You can implement caching to reduce server load.

services.AddMemoryCache();

Step 9. Build and Run the Project

You can now run the project.

dotnet run

The project demonstrates rate limiting, request size limiting, and CAPTCHA integration, which are essential measures to prevent DoS attacks. You can extend this further by adding distributed caching (e.g., Redis) and a WAF.

GitHub Project Link: https://github.com/SardarMudassarAliKhan/DoSAttackPrevention

Conclusion

Implementing DoS attack prevention measures in an ASP.NET Core MVC application is essential to protect your application from malicious traffic and resource exhaustion. By leveraging techniques such as rate limiting, request size limiting, CAPTCHA integration, and input validation, you can significantly enhance the security and resilience of your application. These strategies, along with proper caching and server configurations, ensure that your application can handle legitimate traffic while mitigating the risk of potential attacks, keeping both performance and user experience intact.


Similar Articles