GitHub Actions se ha convertido en una herramienta esencial para la automatización de procesos en el desarrollo de software, permitiendo desde pruebas y compilación hasta despliegues continuos. Sin embargo, a medida que su uso se ha expandido, también lo han hecho las vulnerabilidades y ataques dirigidos a su infraestructura, poniendo en riesgo la integridad de repositorios y datos sensibles. Fortalecer GitHub Actions es ya una prioridad para muchos equipos y organizaciones que desean proteger sus pipelines de integración continua y despliegue continuo (CI/CD). Durante los últimos años, varios incidentes han mostrado cómo los atacantes pueden aprovechar configuraciones inseguras y malas prácticas en los workflows de GitHub Actions para ejecutar código malicioso o exfiltrar secretos valiosos. Un caso emblemático fue la introducción de un cryptominer XMRig mediante la explotación de un workflow vulnerable en la distribución del paquete Python Ultralytics.
Otro incidente notable involucró la acción conocida como “tj-actions”, que facilitó un ataque en cadena mediante el robo de tokens de acceso y la propagación de código maligno en múltiples repositorios. Para evitar caer en estas trampas, es indispensable comprender el funcionamiento de GitHub Actions y aplicar controles estrictos tanto a nivel de organización como de repositorio. Antes de detallar las estrategias para fortalecer tu entorno, conviene entender la terminología fundamental: un workflow es el conjunto de tareas automatizadas que se ejecutan en base a eventos específicos dentro del repositorio; las acciones (o Actions) son unidades reutilizables que componen esos workflows; los eventos son los disparadores que activan los workflows; y los jobs o tareas ejecutan los pasos consistentes dentro del proceso. El primer paso para asegurar GitHub Actions consiste en configurar los permisos de tus workflows. Desde febrero de 2023, GitHub cambió el permiso predeterminado del token de flujo de trabajo (GITHUB_TOKEN) de lectura y escritura a solo lectura, una medida crucial para limitar el potencial dañino en caso de compromisos.
Asegurarse de que tus repositorios utilicen esta configuración es vital para el principio de mínimo privilegio. Revisar y restringir cuidadosamente cualquier permiso adicional que un workflow requiera puede prevenir modificaciones no autorizadas en el código o la divulgación accidental de información confidencial. Otro pilar de la seguridad es el control riguroso sobre qué acciones pueden ejecutarse en tus workflows. Dado que GitHub Actions permite integrar acciones publicadas en el Marketplace por terceros, estas llegan a representar un vector de riesgo significativo. La recomendación es priorizar el uso de acciones verificadas por GitHub o creadas por la propia plataforma, las cuales han pasado por revisiones de seguridad y son consideradas confiables.
Además, establecer una lista blanca de acciones autorizadas y evitar la ejecución de acciones sin control puede reducir exponencialmente la superficie de ataque. Administrar los runners, es decir, los entornos donde se ejecutan las workflows, también juega un rol crucial en la seguridad. Si bien los runners hospedados por GitHub son efímeros y aislados, los runners autohospedados, aunque ofrecen flexibilidad y personalización, pueden ser un riesgo si no se aíslan adecuadamente o si no se monitorean continuamente. Es recomendable segmentar runners por nivel de confianza y evitar que repositorios públicos tengan acceso a runners que ejecutan código sensible para proteger la infraestructura física y lógica de compromisos persistentes. La protección de branches o ramas es otro componente indispensable.
Las ramas principales, de desarrollo y liberación deben estar sujetas a reglas estrictas que limiten quién puede fusionar código y bajo qué condiciones. Configuraciones como rechazar aprobaciones obsoletas cuando se agregan nuevos commits o requerir aprobaciones de revisores distintos a quien hizo el último commit son herramientas que ayudan a mitigar ataques post-aprobación y secuestro de pull requests, técnicas comunes en incidentes dirigidos a pipelines CI/CD. El manejo seguro de secretos es fundamental dentro de cualquier pipeline. GitHub ofrece varios niveles para almacenar secretos: a nivel de repositorio, organización y entorno. Cada uno tiene un propósito particular, pero la recomendación general es mantener los secretos lo más restringidos posible, asignándolos sólo a los workflows y jobs que realmente los necesitan.
Al utilizar variables de entorno, deben pasarse individualmente en lugar de compartir todo el contexto de secretos para evitar exponer información sensible innecesariamente. Es fundamental evitar pasar secretos en workflows reutilizables mediante la herencia implícita y, en cambio, definir explícitamente qué secretos se propagan. Uno de los riesgos recurrentes más peligrosos en GitHub Actions es la ejecución de flujos de trabajo con desencadenantes que permiten al código controlado por un atacante acceder a secretos o permissos elevados. Un claro ejemplo son los triggers "pull_request_target" y "workflow_run", que ejecutan workflows en el contexto del repositorio base con acceso privilegiado, pero pueden ejecutar código de forks no confiables. Esto puede permitir la filtración de secretos o la ejecución de código arbitrario.
Para reducir esta vulnerabilidad, es crucial jamás ejecutar código proveniente de pull requests sin un análisis o autorización previa. La inyección de comandos y la interpolación sin control de valores dinámicos en los archivos YAML de workflows también representan vulnerabilidades críticas. Pasar datos de usuarios o datos externos como argumentos en comandos sin validación puede desencadenar ejecución de comandos maliciosos que comprometen la seguridad del pipeline. Es recomendable validar o sanitizar cualquier input y, cuando sea posible, evitar interpolaciones directas, optando por workflows reutilizables con parámetros bien definidos y controlados. El manejo de artefactos, utilizados para compartir datos entre jobs, debe hacerse con precaución.
Los artefactos pueden inadvertidamente contener credenciales u otra información sensible si no se configuran correctamente, aumentando el riesgo de filtraciones. Herramientas como 'actions/checkout' persisten credenciales de acceso por defecto, por lo que es aconsejable deshabilitar esta característica cuando no sea necesaria para evitar la exposición inadvertida. A pesar de que los runners autohospedados pueden ser atractivos por motivos de rendimiento o personalización, es importante recordar que estos ambientes persisten, lo que los hace objetivos valiosos para atacantes que buscan mantener una presencia prolongada. Por lo tanto, la instrumentación, monitoreo continuo y uso de infraestructura efímera son prácticas recomendadas para minimizar riesgos de compromisos persistentes. Para mitigar la gestión de credenciales a largo plazo y minimizar la exposición de secretos en el pipeline, GitHub Actions soporta la autenticación mediante OpenID Connect (OIDC).
Esta tecnología permite la generación de tokens de corta duración y limitados a una identidad, que se usan para autenticar con proveedores en la nube y sistemas externos, mejorando así el control de acceso y reducción del riesgo asociado a secretos estáticos. Finalmente, para aquellos que buscan un análisis profundo y automatizado de sus configuraciones de GitHub Actions, existen herramientas open source que facilitan la detección de malas prácticas y vulnerabilidades. Proyectos como zizmor ofrecen análisis estático para identificar configuraciones peligrosas, mientras que gato y Gato-X ayudan en la enumeración y ataque para mejorar la detección de riesgos. La aplicación GitHub Allstar ayuda a establecer y aplicar políticas de seguridad uniformes en organizaciones y repositorios. En resumen, proteger GitHub Actions requiere un enfoque integral que incluya la minimización del uso de acciones de terceros, un control estricto de permisos y secretos, la prevención de ejecuciones potencialmente peligrosas y una gestión cuidadosa de runners y artefactos.
Estas prácticas no solo refuerzan la seguridad del pipeline, sino que también contribuyen a mantener la integridad y confidencialidad de los proyectos y datos que se gestionan. Mantenerse informado sobre los últimos incidentes y adoptar una postura proactiva en la seguridad es crucial en un entorno de desarrollo cada vez más automatizado y colaborativo.