feat: Añadidos de seguridad (Backend, Frontend e IA)

Implementación de medidas de seguridad críticas tras auditoría:

Backend (API & IA):
- Anti-Prompt Injection: Reestructuración de prompts con delimitadores XML y sanitización estricta de inputs (Tag Injection).
- Anti-SSRF: Implementación de servicio `UrlSecurity` para validar URLs y bloquear accesos a IPs internas/privadas en funciones de scraping.
- Moderación: Activación de `SafetySettings` en Gemini API.
- Infraestructura:
  - Configuración de Headers de seguridad (HSTS, CSP, NoSniff).
  - CORS restrictivo (solo métodos HTTP necesarios).
  - Rate Limiting global y política estricta para Login (5 req/min).
  - Timeouts en HttpClient para prevenir DoS.
- Auth: Endpoint `setup-admin` restringido exclusivamente a entorno Debug.

Frontend (React):
- Anti-XSS & Tabnabbing: Configuración de esquema estricto en `rehype-sanitize` y forzado de `rel="noopener noreferrer"` en enlaces.
- Validación de longitud de input en cliente.

IA:
- Se realiza afinación de contexto de preguntas.
This commit is contained in:
2025-11-27 15:11:54 -03:00
parent 6f96ca9c79
commit 67e179441d
8 changed files with 539 additions and 443 deletions

View File

@@ -1,4 +1,3 @@
// /Controllers/AuthController.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
@@ -6,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.RateLimiting;
public class LoginRequest
{
@@ -26,7 +26,6 @@ public class AuthController : ControllerBase
private readonly IConfiguration _configuration;
private readonly UserManager<IdentityUser> _userManager;
// Inyectamos el UserManager que gestiona los usuarios
public AuthController(IConfiguration configuration, UserManager<IdentityUser> userManager)
{
_configuration = configuration;
@@ -34,12 +33,11 @@ public class AuthController : ControllerBase
}
[HttpPost("login")]
[EnableRateLimiting("login-limit")]
public async Task<IActionResult> Login([FromBody] LoginRequest loginRequest)
{
// Buscamos al usuario por su nombre
var user = await _userManager.FindByNameAsync(loginRequest.Username);
// Verificamos si el usuario existe y si la contraseña es correcta
if (user != null && await _userManager.CheckPasswordAsync(user, loginRequest.Password))
{
var token = GenerateJwtToken(user);
@@ -49,7 +47,8 @@ public class AuthController : ControllerBase
return Unauthorized("Credenciales inválidas.");
}
// Método para crear el primer usuario administrador (solo para configuración inicial)
#if DEBUG
// [SEGURIDAD] Endpoint solo para desarrollo
[HttpPost("setup-admin")]
public async Task<IActionResult> SetupAdminUser()
{
@@ -61,6 +60,7 @@ public class AuthController : ControllerBase
UserName = "admin",
Email = "tecnica@eldia.com",
};
// En producción usar Secrets, no hardcoded
var result = await _userManager.CreateAsync(adminUser, "Diagonal423");
if (result.Succeeded)
@@ -71,6 +71,7 @@ public class AuthController : ControllerBase
}
return Ok("El usuario administrador ya existe.");
}
#endif
private string GenerateJwtToken(IdentityUser user)
{