Add per-IP sliding-window rate limiting to all auth endpoints

Auth endpoints had no IP-level rate limit; only Identity's per-account
lockout applied. A sliding-window policy (20 requests / 15 min per IP,
no queue) is now registered in Program.cs and applied to AuthController
via [EnableRateLimiting]. Rejected requests receive 429 Too Many Requests.
This commit is contained in:
2026-07-04 14:49:17 +01:00
parent d561613bb3
commit 6f16fd8649
2 changed files with 21 additions and 0 deletions

View File

@@ -43,6 +43,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Configuration;
@@ -52,6 +53,7 @@ namespace Marechai.Server.Controllers;
[ApiController]
[Route("auth")]
[EnableRateLimiting("AuthEndpoints")]
public class AuthController
(UserManager<ApplicationUser> userManager, MarechaiContext context,
TokenService tokenService, IConfiguration configuration,

View File

@@ -2,6 +2,7 @@ using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.RateLimiting;
using System.Text.Json;
using System.Text.Json.Serialization;
using Aaru.CommonTypes.Interop;
@@ -354,6 +355,24 @@ file class Program
builder.Services.AddMarechaiEmail(builder.Configuration);
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
// Strict per-IP limit for all auth endpoints (login, register, 2FA, password reset, etc.)
options.AddPolicy("AuthEndpoints", httpContext =>
RateLimitPartition.GetSlidingWindowLimiter(
httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
_ => new SlidingWindowRateLimiterOptions
{
Window = TimeSpan.FromMinutes(15),
SegmentsPerWindow = 3,
PermitLimit = 20,
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
QueueLimit = 0
}));
});
builder.Services.AddScoped<TokenService, TokenService>();
builder.Services.AddSingleton<InvitationCodeGenerator>();
builder.Services.AddSingleton<AvatarFileCleaner>();