Los equipos que intentan añadir una revisión de seguridad a cada pull request suelen abandonar en un mes. La cola crece, los revisores leen por encima y la etiqueta se vuelve un trámite. El fallo contrario es igual de común: nadie con contexto de seguridad ve el cambio que reescribió la gestión de sesiones.
La respuesta es el enrutado. La mayoría de los diffs tienen poco riesgo de seguridad. Unos pocos concentran casi todo. Si puedes nombrar esos pocos por ruta, puedes enviarlos automáticamente a los revisores adecuados y dejar el resto a la revisión normal entre compañeros y a los escáneres.
Qué merece una persona
Escáneres como Semgrep y Gitleaks son buenos con los patrones: una función peligrosa, un token hardcodeado, una dependencia con problemas conocidos. Son malos con la lógica: si este endpoint comprueba al propietario correcto, si este refactor eliminó una comprobación, si este nuevo rol es demasiado amplio. La revisión humana compensa su coste donde la lógica decide la seguridad.
Las rutas que suelen cumplir el criterio:
- Autenticación y sesiones. Login, emisión de tokens, restablecimiento de contraseña, MFA, almacenamiento de sesión.
- Autorización. Código de políticas, definiciones de roles, middleware que comprueba la propiedad.
- Criptografía. Todo lo que firma, cifra, hashea contraseñas o genera tokens.
- Parsers y manejo de ficheros. Subidas, deserialización, extracción de archivos comprimidos, descarga de URLs.
- Dinero y límites. Pagos, saldos, cuotas, rate limits.
- Infraestructura como código. Políticas de IAM, reglas de red, buckets públicos.
- Configuración de CI y deploy. Ficheros de workflow, scripts de deploy, definiciones de entornos.
Tu lista será distinta. Parte de tu threat model: las rutas de código ligadas a tus objetivos de abuso más importantes son las que hay que dirigir.
Enrútalo con CODEOWNERS
En GitHub, un fichero CODEOWNERS asocia rutas con revisores obligatorios. Combinado con branch protection que exige la aprobación del code owner, el enrutado es automático. Un esquema para un repositorio de servicio típico:
# .github/CODEOWNERS
# Default: the owning team reviews everything
* @example-org/payments-team
# Security-sensitive paths also need a security reviewer
/src/auth/ @example-org/payments-team @example-org/appsec-reviewers
/src/authz/ @example-org/payments-team @example-org/appsec-reviewers
/src/crypto/ @example-org/appsec-reviewers
/src/uploads/ @example-org/payments-team @example-org/appsec-reviewers
/infra/iam/ @example-org/platform @example-org/appsec-reviewers
# Pipeline and ownership rules are themselves sensitive
/.github/workflows/ @example-org/platform @example-org/appsec-reviewers
/.github/CODEOWNERS @example-org/appsec-reviewers
Dos detalles importan. Las reglas posteriores sobrescriben a las anteriores para la misma ruta, así que pon primero el valor por defecto general. Y protege el propio fichero CODEOWNERS, o cualquiera puede quitar una regla en la misma pull request que la necesita.
Quiénes son los revisores
"appsec-reviewers" no tiene por qué ser un equipo de seguridad. En la mayoría de organizaciones funciona mejor como un grupo de security champions: uno o dos desarrolladores por área que han recibido algo de formación y conocen el threat model de su parte del sistema. Revisan con un contexto de dominio que un equipo central no puede igualar.
Dales una checklist corta para las revisiones derivadas, para que la revisión tenga forma:
- ¿Se autentica cada nuevo punto de entrada y comprueba la propiedad del objeto que toca?
- ¿El cambio eliminó o se saltó una comprobación existente?
- ¿Es exactamente lo que publicamos?
- ¿Los secretos, tokens y claves se gestionan con la librería o el almacén aprobados?
- ¿Los errores y logs están libres de datos sensibles?
- ¿El cambio altera un límite de confianza del diagrama de arquitectura?
Más allá de las rutas
Las rutas cubren la mayoría de los casos, pero no todos. Algunos cambios de riesgo viven en ficheros normales. Dos añadidos baratos ayudan:
- Etiquetas por contenido. Un workflow puede añadir una etiqueta
needs-security-reviewcuando un diff toca patrones como rutas nuevas, dependencias nuevas o cambios de permisos, y un ruleset puede exigir la revisión adecuada para esa etiqueta. - Autodeclaración. Una casilla en la plantilla del pull request: "Este cambio afecta a la autenticación, la autorización, los pagos o la exposición de datos." Los autores suelen saberlo.
Mantén el volumen derivado lo bastante bajo para que los revisores lean cada diff. Si la cola crece, ajusta las rutas en lugar de dejar que los revisores lean por encima. Una revisión derivada que tarda un día en empezar se acabará saltando, así que acordad un tiempo de respuesta con el grupo de revisores y mantenedlo.
Qué hacer el lunes
- Lista de cinco a diez directorios de tu repositorio principal donde un bug sería un incidente de seguridad.
- Crea un grupo de revisores de dos o tres personas que conozcan esas áreas.
- Añade las rutas a
CODEOWNERS, incluida la carpeta de workflows y el propio fichero. - Activa «Require review from Code Owners» en la protección de ramas o en los rulesets.
- Tras un mes, cuenta las pull requests enrutadas y ajusta las rutas para que la carga siga siendo razonable.
Dónde encaja en la línea
En la torre (en desarrollo):