Feat: Ajustes de seguridad

This commit is contained in:
2026-01-30 11:18:56 -03:00
parent 32cf2ba74a
commit 8f6f8d4500
10 changed files with 179 additions and 207 deletions

View File

@@ -78,25 +78,28 @@ builder.Services.AddRateLimiter(options =>
options.AddPolicy("AuthPolicy", context =>
{
// Si es localhost, SIN LÍMITES
// Si es localhost, SIN LÍMITES (Evita auto-bloqueo en desarrollo)
var remoteIp = context.Connection.RemoteIpAddress;
if (System.Net.IPAddress.IsLoopback(remoteIp!))
if (remoteIp != null && System.Net.IPAddress.IsLoopback(remoteIp))
{
return RateLimitPartition.GetNoLimiter("loopback_auth");
}
return RateLimitPartition.GetFixedWindowLimiter(
partitionKey: remoteIp?.ToString() ?? "unknown",
factory: _ => new FixedWindowRateLimiterOptions
{
AutoReplenishment = true,
PermitLimit = 5, // 5 intentos por minuto para IPs externas
QueueLimit = 0,
Window = TimeSpan.FromMinutes(1)
});
return RateLimitPartition.GetFixedWindowLimiter("auth_limit", _ => new FixedWindowRateLimiterOptions
{
PermitLimit = 5,
Window = TimeSpan.FromMinutes(1),
QueueLimit = 0
});
});
});
// 🛡️ SEGURIDAD: Evitar que el host se caiga si un servicio de fondo falla
builder.Services.Configure<HostOptions>(options =>
{
options.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore;
});
// DB CONTEXTS (Legacy unificado en eldia)
builder.Services.AddDbContext<EldiaDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("eldia")));
@@ -119,6 +122,7 @@ builder.Services.Configure<MailSettings>(builder.Configuration.GetSection("SmtpS
builder.Services.AddScoped<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<IImageStorageService, ImageStorageService>();
builder.Services.AddHostedService<AdExpirationService>();
builder.Services.AddHostedService<TokenCleanupService>();
// 🔒 JWT AUTH
var jwtKey = builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("JWT Key Missing");
@@ -158,8 +162,10 @@ builder.Services.AddSwaggerGen();
var app = builder.Build();
// USAR EL MIDDLEWARE AL PRINCIPIO
// Debe ser lo primero para que el RateLimiter y los Logs vean la IP real
// Middleware de Manejo Global de Excepciones (Debe ser el primero para atrapar todo)
app.UseMiddleware<MotoresArgentinosV2.API.Middleware.ExceptionHandlingMiddleware>();
// USAR EL MIDDLEWARE DE HEADERS
app.UseForwardedHeaders();
// 🔒 HEADERS DE SEGURIDAD MIDDLEWARE
@@ -170,6 +176,9 @@ app.Use(async (context, next) =>
context.Response.Headers.Append("Referrer-Policy", "strict-origin-when-cross-origin");
context.Response.Headers.Append("X-XSS-Protection", "1; mode=block");
// Permissions-Policy: Bloquear funcionalidades sensibles del navegador no usadas
context.Response.Headers.Append("Permissions-Policy", "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()");
// CSP adaptada para permitir pagos en Payway y WebSockets de Vite
string csp = "default-src 'self'; " +
"img-src 'self' data: https: blob:; " +