Skip to content

Security: jeremy-sud/Senselab_Core_API

SECURITY.md

🔐 Guía de Seguridad - Senselab Core API

Última actualización: 17 de Abril de 2026
Versión: 5.0.1
Clasificación: Documento Interno de Seguridad
Auditor: Verificación de Código Actual + Mejoras Implementadas (FASE 1-22)


📋 Tabla de Contenidos

  1. OWASP Top 10 - Implementación
  2. Gestión de Dependencias (pnpm)
  3. Autenticación y Autorización
  4. Protección de Datos
  5. Configuración Segura
  6. Auditoría y Monitoreo
  7. Respuesta a Incidentes

🔐 MEJORAS IMPLEMENTADAS (FEBRERO 2026)

FASE 1.5 - Rate Limiting Granular ✅

  • 7 Limiters independientes configurados con diferentes umbrales
  • Servicio centralizado RateLimitingService (253 líneas)
  • Middleware mejorado ThrottleRequestsWithRetryAfter con header 429
  • IP blocking tras múltiples violaciones
  • Listas de excepción inteligentes

Configuración:

API General:      60 reqs/min
Reportes:         5 generaciones/hora
Importaciones:    2/día
Exportaciones:    5/día
Hacienda:         10 envíos/hora
Login:            5 intentos/15 min
Payment:          3 transacciones/hora

FASE 1.6 - Encriptación AES-256-CBC ✅

  • 30+ campos sensibles encriptados automáticamente
  • Búsqueda hash-based sin desencriptar datos
  • Soporte rotación de claves para cumplimiento normativo
  • Control de acceso por IP y rol
  • Campos protegidos:
    • Usuario: email, teléfono, identificación
    • Empresa: CIF, banco, código DANE
    • Proveedor: cuenta bancaria
    • Transacción: detalles financieros
  • Audit trail completo de acceso

FASE 1.7 - Auditoría Completa ✅

  • AuditLog Model con 23 columnas
  • CRUD automático en todos los modelos
  • GDPR/LGPD compliance - Right-to-be-forgotten implementado
  • Máscaras automáticas de valores sensibles
  • Retención configurable (90 días default)
  • Full-text search en cambios de datos
  • 13 Scopes para análisis y reporting

FASE 2.1 - Hacienda Integration ✅

  • HaciendaComprobante Model con 13 scopes
  • Servicios refactorizados: HaciendaApiClient (HTTP + rate limiting), FirmaDigitalService (XAdES-EPES), OAuthTokenManager (OAuth 2.0), XmlComprobanteBuilder (XML v4.4)
  • Generador de clave de 50 dígitos (Algoritmo Mod-9)
  • Firma digital XAdES-EPES implementada
  • 8 endpoints REST para gestión completa
  • Estados: pending, signed, sent, accepted, rejected, error

FASES 4-16 — Mejoras Adicionales de Seguridad (Febrero-Marzo 2026) ✅

FASE Mejora de Seguridad Impacto
4 PHPStan Level 8 — 0 errores, baseline vacío Type safety real, eliminados ~2,000 ignores
13 Eliminación CQRS dead code — 34 archivos Superficie de ataque reducida
14 Contract Testing (Pact) + Mutation Testing (Infection) Verificación de contratos API, calidad de tests
14 Load Testing (k6) — smoke, carga, detección N+1 Resiliencia ante picos de tráfico
15 11 excepciones de dominio con handler centralizado Ya NO se expone $e->getMessage() al cliente
15 ApiResponse trait — envelope unificado Respuestas consistentes: {success, code, message, data, errors, meta}
16 BaseService abstracto con hooks tipados Lógica de negocio aislada de controladores
16 63 DTOs con readonly y fromRequest() Validación de tipos en capa de transferencia (~65% cobertura)
17 Rate limiting normalizado + SecurityHeaders middleware Headers OWASP aplicados globalmente
18 API Versionado /api/v1/ y /api/v2/ Middleware Sunset para deprecación controlada
18.5 Seeders MasterData/DemoData separados Datos de producción aislados de datos demo
19.2 Contract Testing con Pact PHP Verificación de contratos entre consumidor/proveedor
19.3 Mutation Testing con Infection PHP MSI ≥50%, cobertura mutaciones ≥70%
19.4 CI Pipeline Mejorado (Codecov, PHPStan L8) 9 workflows CI/CD con umbrales de calidad
19.6 Hacienda v4.4 — 38/38 brechas cerradas Compliance normativo 100%
19.7 PHPStan 0 errores + DTO 65% + DT limpia Type safety real + factories verificadas
20 Webhooks + Event-Driven HMAC-SHA256, SSRF validation, backoff exponencial
21 Reporting Engine (P&L, Balance, KPIs) Reportes financieros + exportación PDF/Excel/CSV
22 Escalabilidad (Read Replicas, Horizon, ETag, Tracing) OpenTelemetry, ETags 304, distributed tracing

Resultado acumulado: 1270+ tests passing, PHPStan L8 0 errors, 9 workflows CI/CD, 80 policies RBAC.


🔐 OWASP Top 10 — Implementación Completa

A01:2021 - Broken Access Control ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • Policies Laravel: 80+ políticas de autorización implementadas
  • Multi-tenancy: Aislamiento completo de datos por empresa
  • Middleware: EmpresaMiddleware para validación de contexto
  • Scopes globales: EmpresaScope aplicado automáticamente a queries
// Ejemplo de protección en controladores
public function show(Factura $factura): JsonResponse
{
    $this->authorize('view', $factura); // Policy check
    // ...
}

Archivos clave:

  • app/Policies/* - 80+ archivos de políticas
  • app/Models/Scopes/EmpresaScope.php
  • app/Http/Middleware/EmpresaMiddleware.php

A02:2021 - Cryptographic Failures ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • Contraseñas: Bcrypt con cost factor 12
  • Tokens: Laravel Sanctum con tokens SHA-256
  • Certificados: XAdES-EPES para firma digital
  • TLS: Forzado en producción (HTTPS)
  • Datos sensibles: Encriptados con APP_KEY
// Configuración de encriptación
'cipher' => 'AES-256-CBC',
'key' => env('APP_KEY'), // 256-bit key

Variables de entorno sensibles:

APP_KEY=base64:... # Clave de encriptación
DB_PASSWORD=...     # Nunca en código
HACIENDA_P12_PASSWORD=... # Certificado digital

A03:2021 - Injection ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • SQL Injection: Eloquent ORM con bindings
  • XSS: Blade escaping automático
  • Command Injection: shell_exec() presente SOLO en FirmaDigitalService::convertirP12Legacy() con escapeshellarg() estricto (conversión de certificados .p12 legacy). HealthCheckController ya NO usa shell_exec() (resuelto DT-7).
  • LDAP Injection: No aplica
// ✅ Seguro - Eloquent con bindings
$productos = Producto::where('nombre', 'like', "%{$search}%")->get();

// ❌ NUNCA hacer esto
// DB::raw("SELECT * FROM productos WHERE nombre = '$search'");

FormRequest Validation:

public function rules(): array
{
    return [
        'email' => ['required', 'email:rfc,dns'],
        'codigo' => ['required', 'string', 'max:50', 'regex:/^[A-Z0-9-]+$/'],
    ];
}

A04:2021 - Insecure Design ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • Arquitectura: Separación de capas (Controllers → Services → DTOs → Models)
  • BaseService abstracto: Hooks tipados (beforeCreate, afterCreate, applyFilters) — FASE 16
  • 63 DTOs con propiedades readonly y factory fromRequest() — FASES 16-19.7 (~65% cobertura)
  • 11 excepciones de dominio con handler centralizado — FASE 15
  • ApiResponse trait: Envelope unificado, sin exposición de errores internos — FASE 15
  • 170+ FormRequests con validación comprehensiva
  • Rate Limiting: 7 limitadores granulares por contexto
// Rate limiting configurado
Route::middleware(['throttle:api'])->group(function () {
    // 60 requests por minuto por defecto
});

Route::middleware(['throttle:login'])->post('/login', ...);
// 5 intentos por minuto

A05:2021 - Security Misconfiguration ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • DEBUG: Deshabilitado en producción
  • Headers: Configurados correctamente
  • CORS: Restrictivo por defecto
  • Error Messages: Genéricos en producción
// config/app.php
'debug' => env('APP_DEBUG', false),

// config/cors.php
'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '')),

Headers de seguridad recomendados (nginx):

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;

A06:2021 - Vulnerable and Outdated Components ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • pnpm: Gestor de paquetes seguro (no npm)
  • Composer audit: Verificación de vulnerabilidades
  • Dependabot: Alertas automáticas en GitHub
  • Actualizaciones: Proceso regular de actualización
# Auditoría de seguridad
composer audit
pnpm audit

# Actualización segura
composer update --with-all-dependencies
pnpm update --latest

A07:2021 - Identification and Authentication Failures ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • Laravel Sanctum: Tokens seguros para API
  • Password Policy: Mínimo 8 caracteres, complejidad
  • Session Management: Tokens con expiración
  • Multi-factor: Preparado para implementar
// config/sanctum.php
'expiration' => 60 * 24, // 24 horas

// Validación de contraseñas
'password' => ['required', Password::min(8)->mixedCase()->numbers()],

A08:2021 - Software and Data Integrity Failures ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • pnpm lockfile: Integridad verificada
  • Composer.lock: Versiones fijadas
  • CI/CD: Pipeline seguro
  • Firma digital: XAdES-EPES para facturas
# pnpm verifica integridad automáticamente
pnpm install --frozen-lockfile

A09:2021 - Security Logging and Monitoring Failures ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • Laravel Logging: Configurado para producción
  • Sentry: Monitoreo de errores
  • Audit Trail: Registros de cambios
  • Activity Log: Acciones de usuario
// config/logging.php
'channels' => [
    'stack' => [
        'channels' => ['daily', 'sentry'],
    ],
],

A10:2021 - Server-Side Request Forgery (SSRF) ✅

Estado: IMPLEMENTADO

Medidas aplicadas:

  • URLs validadas: Solo dominios permitidos
  • Timeout: Configurado en requests externos
  • Hacienda API: URLs fijas, no dinámicas
// Solo URLs de Hacienda permitidas
private const HACIENDA_URLS = [
    'production' => 'https://api.comprobanteselectronicos.go.cr',
    'sandbox' => 'https://api-sandbox.comprobanteselectronicos.go.cr',
];

📦 Gestión de Dependencias (pnpm)

¿Por qué pnpm en lugar de npm?

Característica npm pnpm
Almacenamiento Duplicados Content-addressable
Velocidad Lento 2-3x más rápido
Seguridad Vulnerable a supply chain Mejor aislamiento
Integridad Básica Verificación estricta
Espacio en disco Alto Mínimo

Instalación de pnpm

# Instalación global
npm install -g pnpm

# O con corepack (recomendado)
corepack enable
corepack prepare pnpm@latest --activate

# Verificar instalación
pnpm --version

Comandos de seguridad

# Auditoría de vulnerabilidades
pnpm audit

# Actualizar con parches de seguridad
pnpm update --latest

# Verificar integridad del lockfile
pnpm install --frozen-lockfile

# Listar dependencias outdated
pnpm outdated

Configuración (.npmrc)

# Usar pnpm exclusivamente
only-allow-pnpm=true

# Verificar integridad
verify-store-integrity=true

# Auditoría automática
audit=true

🔑 Autenticación y Autorización

Laravel Sanctum

// Protección de rutas API
Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('facturas', FacturaController::class);
});

Policies

// Autorización granular
class FacturaPolicy
{
    public function view(User $user, Factura $factura): bool
    {
        return $user->empresa_id === $factura->empresa_id;
    }
}

Roles y Permisos

El sistema implementa RBAC (Role-Based Access Control) con 68 permisos y 8 roles:

  • Administrador: Acceso total al sistema
  • Gerente: Gestión de su empresa (ventas, compras, reportes)
  • Contador: Contabilidad, nómina, declaraciones tributarias
  • Vendedor: Ventas, clientes, productos
  • Bodeguero: Inventario, almacenes, movimientos
  • Cajero: Caja, cobros, pagos
  • RRHH: Empleados, nómina, períodos
  • Auditor: Lectura de auditoría, logs, compliance

80+ policies con BasePolicy compartida, doble capa (middleware permission:X + Policy).


🛡️ Protección de Datos

Datos en Tránsito

  • TLS 1.3 obligatorio en producción
  • HSTS habilitado
  • Certificados válidos

Datos en Reposo

  • Encriptación AES-256
  • Hashing Bcrypt para contraseñas
  • Backups encriptados

Datos Sensibles

// Modelo con campos ocultos
protected $hidden = [
    'password',
    'remember_token',
    'p12_password',
];

// Campos encriptados
protected $casts = [
    'password' => 'hashed',
    'datos_sensibles' => 'encrypted',
];

⚙️ Configuración Segura

Variables de Entorno

# Producción
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.tudominio.com

# Base de datos
DB_CONNECTION=mysql
DB_HOST=127.0.0.1  # No exponer externamente

# Cache y sesiones
SESSION_DRIVER=redis
CACHE_DRIVER=redis

# Logging
LOG_CHANNEL=stack
LOG_LEVEL=warning

Headers HTTP

// Middleware de seguridad recomendado
public function handle($request, $next)
{
    $response = $next($request);
    
    return $response
        ->header('X-Frame-Options', 'DENY')
        ->header('X-Content-Type-Options', 'nosniff')
        ->header('X-XSS-Protection', '1; mode=block')
        ->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}

📊 Auditoría y Monitoreo

Logs de Seguridad

// Registrar eventos importantes
Log::channel('security')->info('Login exitoso', [
    'user_id' => $user->id,
    'ip' => $request->ip(),
    'user_agent' => $request->userAgent(),
]);

Alertas

  • Intentos de login fallidos (> 5)
  • Acceso denegado repetido
  • Cambios en roles/permisos
  • Errores 500 en producción

Sentry Integration

// config/sentry.php
'dsn' => env('SENTRY_LARAVEL_DSN'),
'traces_sample_rate' => 0.2,

🚨 Respuesta a Incidentes

Proceso

  1. Detección: Monitoreo automático + reportes
  2. Contención: Aislar el problema
  3. Erradicación: Eliminar la causa
  4. Recuperación: Restaurar operaciones
  5. Lecciones: Documentar y mejorar

Contactos de Seguridad

Checklist de Incidente

  • Identificar alcance
  • Notificar equipo
  • Preservar evidencia
  • Contener amenaza
  • Comunicar a afectados
  • Documentar timeline
  • Implementar mejoras

📝 Reporte de Vulnerabilidades

Si encuentras una vulnerabilidad de seguridad:

  1. NO publiques públicamente
  2. Envía email a: [email protected]
  3. Incluye:
    • Descripción detallada
    • Pasos para reproducir
    • Impacto potencial
    • Sugerencia de fix (opcional)

Respondemos en máximo 48 horas hábiles.


✅ Checklist de Despliegue Seguro

Pre-producción

  • APP_DEBUG=false
  • APP_ENV=production
  • HTTPS configurado
  • Firewall activo
  • Base de datos no expuesta
  • Redis protegido
  • Logs configurados
  • Backups automáticos
  • Monitoreo activo

Post-despliegue

  • Verificar headers de seguridad
  • Probar autenticación
  • Verificar rate limiting
  • Revisar logs por errores
  • Confirmar SSL/TLS


📊 Estado de Seguridad (Marzo 2026)

Métrica Valor
PHPStan Level 8, 0 errores
Tests 997 passing (100%)
OWASP Top 10 10/10 cubiertos
Políticas RBAC 80+
Campos encriptados 30+ (AES-256-CBC)
Rate limiters 7 independientes
Security headers 8 (OWASP compliant)
CI/CD workflows 7 (incluye quality gates)
Excepciones dominio 11 tipadas con handler
Contract tests 6 (Pact PHP)
Mutation testing MSI ≥ 50%, Covered ≥ 70%

Documento mantenido por Senselab — Actualizado v4.2.0, 10 de abril de 2026

There aren't any published security advisories