7. Gestión de secretos
Temas del programa: 3.4.3 y 3.4.4
Qué es un secreto
Section titled “Qué es un secreto”Cualquier valor que da acceso a algo · si otra persona lo tiene puede actuar como tú o como tu sistema
DB_PASSWORD · usuario y contraseña de servicios
APP_KEY · llaves de API de terceros
Tokens de Sanctum · tokens de acceso de GitLab
No son secretos APP_NAME · DB_HOST de tu máquina · el puerto · van en .env.example con su valor
Dónde vive cada secreto
Section titled “Dónde vive cada secreto”| Ambiente | Dónde | Quién lo ve |
|---|---|---|
| Tu máquina | .env fuera del repositorio | Solo tú |
| Pruebas locales | .env o .env.testing ignorados | Solo tú |
| Pipeline de CI | Variables de CI/CD de GitLab | El pipeline · enmascaradas en el log |
| Producción | La plataforma de despliegue | En el Bloque IV profundizarás en esto |
El camino de un secreto en Laravel
Section titled “El camino de un secreto en Laravel”.env DB_PASSWORD=clave-local-de-ana ▼config/database.php 'password' => env('DB_PASSWORD'), ▼tu código config('database.connections.pgsql.password')// Mal: el secreto queda en el repositorio para siempre$cliente = new ServicioCorreo('sk_live_8f3a...');
// Bien: se lee de la configuración$cliente = new ServicioCorreo(config('services.correo.key'));env() solo dentro de config/ · el resto del código usa config()
.env y .env.example
Section titled “.env y .env.example”DB_PASSWORD=clave-local-de-ana
APP_KEY=base64:Qm9...
DB_PASSWORD=
APP_KEY=
cp .env.example .envphp artisan key:generateUna persona nueva levanta el proyecto con dos comandos sin recibir tus credenciales · STD-SEC-02
Retomando .gitignore
Section titled “Retomando .gitignore”En el Bloque II viste qué no entra al repositorio · ahora interesa cómo decide Git y dónde puede fallar
# Entorno y secretos.env.env.*!.env.example
# Generados/vendor/node_modules.phpunit.result.cache/storage/*.keyrecursos/estandares/config-examples/.gitignore adaptado a un proyecto en la raíz
Cómo lee Git un .gitignore
Section titled “Cómo lee Git un .gitignore”| Patrón | Significa |
|---|---|
.env | Cualquier archivo llamado .env |
.env.* | .env.testing · .env.production · .env.backup |
!.env.example | Excepción · este sí se versiona |
/vendor | La carpeta vendor de la raíz solamente |
*.log | Cualquier archivo que termine en .log |
# texto | Comentario |
Se leen de arriba hacia abajo · la última regla que coincide gana · por eso el ! va después
Comprobar en lugar de suponer
Section titled “Comprobar en lugar de suponer”$ git check-ignore -v .env.gitignore:2:.env .env
$ git check-ignore -v .env.testing.gitignore:3:.env.* .env.testing
$ git status --ignored --short!! .env!! vendor/check-ignore dice qué línea del .gitignore decide el destino de cada archivo
La trampa — .gitignore no deja de rastrear
Section titled “La trampa — .gitignore no deja de rastrear”.gitignore solo afecta archivos que Git todavía no rastrea · si .env ya se había agregado seguirá subiendo cambios
$ git ls-files .env.env # Git lo rastrea aunque esté en .gitignore
$ git rm --cached .env # deja de rastrearlo y conserva tu archivo local$ git commit -m "chore: dejar de versionar .env"Esto lo saca de los commits futuros · los anteriores lo siguen teniendo
Si un secreto llegó al historial
Section titled “Si un secreto llegó al historial”git log --all --oneline -- .envCambiar la contraseña o generar una llave nueva
Al equipo y al docente
Corregir .gitignore y verificar con check-ignore
Detectarlo antes de que alguien lo use
Section titled “Detectarlo antes de que alguien lo use”git status y git diff --staged · ¿hay un .env o una llave?
El pipeline revisa todo el historial con una herramienta de detección de secretos
Finding: DB_PASSWORD=REDACTEDFile: config/database.phpCommit: 3f2a1b0STD-SEC-03 · salida ilustrativa con el secreto ocultado
Configuración insegura
Section titled “Configuración insegura”El 500 muestra archivos líneas y datos de conexión
El cliente recibe un mensaje genérico y el detalle queda en el log
APP_DEBUG=true solo en tu máquina · en cualquier otro ambiente APP_ENV=production y APP_DEBUG=false
OWASP Top 10:2025
Section titled “OWASP Top 10:2025”| A01 Broken Access Control | A02 Security Misconfiguration | A03 Software Supply Chain Failures | A04 Cryptographic Failures |
| A05 Injection | A06 Insecure Design | A07 Authentication Failures | A08 Software or Data Integrity Failures |
| A09 Security Logging and Alerting Failures | A10 Mishandling of Exceptional Conditions |
top10.owasp.org/2025 consultado 2026-10-20 · el estándar del proyecto aún cita la edición 2021
Las cuatro del programa
Section titled “Las cuatro del programa”A05 · datos del usuario dentro del SQL
A01 A02 A10 · datos ajenos o detalles internos
A02 · debug abierto o CORS sin control
A03 · composer audit
A10 es exactamente el tema de manejo de errores · un error mal controlado también es una vulnerabilidad
Inyección en una línea
Section titled “Inyección en una línea”// VulnerableDB::select("SELECT * FROM equipos WHERE nombre = '{$request->nombre}'");
// SeguroEquipo::where('nombre', $request->validated('nombre'))->get();Con x’ OR ‘1’=‘1 la primera consulta devuelve todo
Actividad A6 — mapa de amenazas de tu proyecto
Relación con el laboratorio
Section titled “Relación con el laboratorio”Este tema se practica en el Laboratorio 4 — Desarrollo seguro.
Qué sigue
Section titled “Qué sigue”Continúa con 8. Integración continua.

