Skip to content

09. Estándar de Seguridad

CampoValor
CódigoSTD-SEC
Versión1.0
EstadoVigente
PropietarioDocente/Arquitecto
Fecha2026-08-30

Establecer un nivel de seguridad realista y verificable, alineado con el OWASP Top 10:2021, sin exigir infraestructura de seguridad de nivel empresarial.

Pendiente de verificación: confirmar en owasp.org si una edición posterior del OWASP Top 10 (p. ej. 2025) ya es la vigente; de ser así, realinear los nombres y agrupaciones de categoría de la sección 15 y actualizar la referencia de la sección 17. Las prácticas concretas de este documento (hashing, control de acceso, injection, etc.) no dependen de la edición.

IDReglaPrioridadNivel
STD-SEC-01Ningún secreto (contraseñas, API keys, tokens) se sube al repositorio; siempre vía .env, que está en .gitignore.P0OBLIGATORIO
STD-SEC-02Se provee un .env.example con las variables necesarias, sin valores reales.P1OBLIGATORIO
STD-SEC-03El pipeline de CI ejecuta secret scanning (Gitleaks) en cada push/PR.P0OBLIGATORIO
STD-SEC-04Si un secreto se sube por error, se rota inmediatamente (no basta con borrarlo del commit siguiente; el historial de Git lo conserva).P0OBLIGATORIO

3. Autenticación y hashing de contraseñas

Section titled “3. Autenticación y hashing de contraseñas”
  • Las contraseñas nunca se almacenan en texto plano ni con hash reversible; se usa bcrypt/argon2 vía el sistema de hashing de Laravel (Hash::make()) — P0/OBLIGATORIO.
  • La autenticación de la API usa Sanctum (Doc. 05); las sesiones/tokens tienen expiración razonable — P1/OBLIGATORIO.
  • Toda acción sensible (editar, eliminar, ver datos de otro usuario) se valida con Policies, no se asume que “si llegó autenticado, puede hacer todo” — P0/OBLIGATORIO.
  • Se usa Eloquent/Query Builder con bindings parametrizados; nunca se concatena input de usuario directamente en SQL crudo (DB::raw con interpolación de variables) — P0/OBLIGATORIO.

Incorrecto:

DB::select("SELECT * FROM users WHERE email = '{$request->email}'"); // Inyección SQL

Correcto:

User::where('email', $request->email)->first();
  • El frontend nunca inyecta datos de usuario/API vía innerHTML sin sanitizar (Doc. 03) — P0/OBLIGATORIO.
  • Laravel Blade escapa por defecto con {{ }}; si se usa {!! !!} (sin escape), debe justificarse explícitamente — P0/OBLIGATORIO.
  • Para rutas de API consumidas por SPA vía Sanctum, se usa el mecanismo de protección CSRF de Sanctum (cookie + header) cuando aplica al flujo de autenticación por cookies; para tokens Bearer puros, CSRF no aplica de la misma forma pero se documenta explícitamente qué mecanismo se usa — P1/OBLIGATORIO.
  • Ya cubierto en Doc. 02 (STD-BE-M01): $fillable explícito siempre, nunca $guarded = [] — P0/OBLIGATORIO.
  • Toda entrada del usuario (body, query params, headers relevantes, archivos) se valida antes de usarse — P0/OBLIGATORIO (Doc. 02, FormRequests).
  • Los endpoints de autenticación (login, registro, recuperación de contraseña) tienen rate limiting explícito (throttle middleware de Laravel) — P1/OBLIGATORIO.
  • Endpoints públicos de alto costo (búsquedas, reportes) tienen rate limiting razonable — P2/RECOMENDADO.
  • Se configura config/cors.php con los orígenes explícitamente permitidos (el dominio del frontend del proyecto), nunca * en producción si hay credenciales involucradas — P1/OBLIGATORIO.
  • Se valida tipo MIME real (no solo extensión), tamaño máximo, y se almacenan fuera del document root público directo cuando sea posible, o con nombres no adivinables — P1/OBLIGATORIO si el proyecto maneja uploads.
  • Nunca se ejecuta un archivo subido por el usuario como código — P0/OBLIGATORIO.
  • Los logs no contienen contraseñas, tokens completos, ni datos personales sensibles innecesarios — P0/OBLIGATORIO (ya referenciado en Doc. 02).
  • Los mensajes de error al usuario final no revelan detalles internos (versión de framework, rutas de servidor, queries) — P0/OBLIGATORIO.
  • Se ejecuta auditoría de dependencias conocidas con vulnerabilidades (composer audit, npm audit) periódicamente y en CI — P2/RECOMENDADO (AVANZADO integrarlo como gate estricto; se recomienda al menos como reporte visible).
  • No se agregan paquetes de fuentes no oficiales/sin mantenimiento sin revisión — P1/OBLIGATORIO.

15. Mapeo al OWASP Top 10:2021 (referencia)

Section titled “15. Mapeo al OWASP Top 10:2021 (referencia)”
OWASP Top 10:2021 (categoría)Cómo se cubre en este proyecto
Broken Access ControlPolicies + Sanctum (secciones 3-4)
Cryptographic FailuresHashing con bcrypt/argon2, HTTPS en despliegue (fuera de alcance de código, pero exigido en infraestructura)
InjectionEloquent/Query Builder parametrizado (sección 5)
Insecure DesignADRs y revisión arquitectónica (Doc. 10)
Security Misconfiguration.env correcto, CORS explícito, APP_DEBUG=false en producción
Vulnerable ComponentsAuditoría de dependencias (sección 14)
Auth FailuresRate limiting en login, expiración de tokens
Software/Data Integrity FailuresCI con checks obligatorios antes de merge
Logging FailuresSección 13
SSRFFuera del alcance típico de este proyecto; si se agregan integraciones que hacen requests a URLs provistas por usuario, se valida el destino — AVANZADO

Además de STD-SEC-01…04 (sección 2), las reglas P0/P1 de este documento, para su referencia desde la Matriz de Cumplimiento (Doc. 14):

IDReglaPrioridadSección
STD-SEC-05Contraseñas con bcrypt/argon2 vía Hash::make(); nunca texto plano ni hash reversible.P03
STD-SEC-06La autenticación de la API usa Sanctum con expiración razonable de sesiones/tokens.P13
STD-SEC-07Toda acción sensible se valida con Policies (autorización explícita, no implícita).P04
STD-SEC-08Acceso a datos con Eloquent/Query Builder parametrizado; nunca SQL crudo con interpolación de input.P05
STD-SEC-09El frontend no usa innerHTML con datos sin sanitizar; Blade sin escape ({!! !!}) se justifica.P06
STD-SEC-10Se documenta explícitamente el mecanismo CSRF usado (cookie+header de Sanctum para SPA; N/A para Bearer puro).P17
STD-SEC-11$fillable explícito siempre (Mass Assignment); ver Doc. 02, STD-BE-M01.P08
STD-SEC-12Toda entrada del usuario (body, query, headers, archivos) se valida antes de usarse.P09
STD-SEC-13Los endpoints de autenticación (login, registro, recuperación) tienen rate limiting explícito.P110
STD-SEC-14config/cors.php con orígenes explícitos; nunca * con credenciales en producción.P111
STD-SEC-15Uploads: se valida tipo MIME real, tamaño máximo y almacenamiento no adivinable/fuera del docroot.P112
STD-SEC-16Nunca se ejecuta un archivo subido por el usuario como código.P012
STD-SEC-17Logs y errores al usuario final no revelan secretos ni detalles internos.P013
STD-SEC-18No se agregan paquetes de fuentes no oficiales o sin mantenimiento sin revisión.P114
ReglaVerificaciónHerramienta
Sin secretos en el repoAutomáticaGitleaks en CI
Mass Assignment / $fillableAutomática (Larastan) + manualPHPStan/Larastan + Review
SQLi (uso de raw queries inseguras)Manual + parcial automáticaCode Review + regla estática si se configura
XSS en frontendManualCode Review (Doc. 03)
Rate limiting en loginManual + testFeature test que verifica 429 tras N intentos
CORS configuradoManualRevisión de config/cors.php en PR de setup
Auditoría de dependenciasAutomática (reporte)composer audit / npm audit en CI
  • OWASP Top 10:2021 (owasp.org/Top10). Verificar edición vigente antes de cada semestre (ver nota de la sección 1).
  • Documentación de seguridad de Laravel y de Laravel Sanctum.
  • Doc. 02 (Mass Assignment, excepciones) y Doc. 05 (autenticación de API).

Fin del documento 09. Continúa en 10. Estándar de Documentación.