1 puntos por GN⁺ 2025-10-17 | 1 comentarios | Compartir por WhatsApp
  • El investigador comparte cómo descubrió vulnerabilidades en Nixpkgs que le habrían permitido inyectar código malicioso en todo el ecosistema de Nix
  • Explica el riesgo estructural de GitHub Actions con el trigger pull_request_target, donde incluso los PR de colaboradores externos pueden exponer permisos sensibles y secretos
  • Demuestra que realmente era posible escalar privilegios en editorconfig-checker y en la validación de code owners mediante inyección de comandos y uso de enlaces simbólicos
  • Tras el hallazgo, el equipo mantenedor de Nixpkgs corrigió rápidamente las vulnerabilidades, desactivó los workflows vulnerables y revisó el manejo de permisos
  • Se enfatiza la importancia de separar los datos no confiables de las operaciones sensibles en la infraestructura CI/CD, aplicar mínimo privilegio y reforzar las políticas

Hackeando todo el ecosistema de Nix

Introducción y contexto

  • En la NixCon del año pasado, el investigador y su colega Lexi presentaron una vulnerabilidad en Nixpkgs
  • La vulnerabilidad descubierta abría la posibilidad de insertar código malicioso en todo el ecosistema de Nix mediante un ataque a la cadena de suministro
  • Fue una experiencia de respuesta rápida: desde la detección y el reporte hasta la mitigación, todo ocurrió en un solo día
  • Como este año el investigador no pudo asistir a la NixCon, decidió documentar el proceso en detalle en este artículo

GitHub Actions: un objetivo vulnerable

  • GitHub Actions es un sistema que permite diversas tareas de automatización (CI/CD) en repositorios de código
  • Si se tiene acceso para modificar archivos de workflow, es fácil insertar código, por lo que se convierte en un blanco principal para ataques a la cadena de suministro
  • Los archivos de workflow están escritos en YAML y, como no es un formato diseñado para ejecución, pueden aparecer vulnerabilidades de seguridad inesperadas
  • Como ejemplo simple, existe un workflow que ejecuta comandos cuando se hace push de código

El peligroso trigger pull_request_target

  • GitHub Actions tiene varios triggers, y entre ellos pull_request_target se diferencia mucho de pull_request
  • pull_request_target tiene por defecto permisos de lectura/escritura y acceso a secretos incluso desde forks (PR)
  • Si se usa mal este trigger, datos externos no confiables pueden combinarse con permisos sensibles
  • La documentación oficial de GitHub también advierte claramente sobre este riesgo
  • El investigador revisó 14 workflows que usaban pull_request_target dentro del repositorio Nixpkgs

Vulnerabilidad en editorconfig-checker

  • El primer workflow vulnerable encontrado tenía como objetivo verificar reglas de editorconfig
  • Después de calcular la lista de archivos modificados, la pasaba a editorconfig-checker usando xargs
  • Si se ignoran las advertencias de seguridad del comando xargs, aparece una vulnerabilidad que permite insertar nombres de archivo diseñados de forma maliciosa (por ejemplo, --help)
  • Esto permitiría manipular editorconfig-checker de forma arbitraria o incluso abrir la puerta a ejecución adicional de comandos (el análisis detallado requiere revisión adicional)

Vulnerabilidad en codeowners-validator: inclusión de archivos locales

  • La segunda vulnerabilidad, y más grave, se encontró en el workflow de validación del archivo CODEOWNERS
  • Este proceso hacía checkout del código del PR y luego verificaba los archivos con codeowners-validator
  • Quien enviaba el PR podía reemplazar un archivo OWNERS por un enlace simbólico, permitiéndole apuntar a archivos arbitrarios dentro del runner (por ejemplo, credenciales de la acción)
  • Como resultado, durante la validación el contenido de ese archivo se imprimía en los logs, lo que exponía un token de GitHub con permisos de lectura/escritura
  • Con ese token, era posible hacer push directamente al repositorio de Nixpkgs

Medidas y lecciones

  • Después del reporte, el mantenedor principal de Nixpkgs, infinisil, respondió de inmediato
    • Desactivó temporalmente los workflows vulnerables
    • Corrigió y separó las partes donde se combinaban datos no confiables con privilegios
    • Tras aplicar los parches de seguridad, cambió los nombres de los workflows para mitigar problemas de branch targeting
  • Lecciones principales
    • Nunca combinar datos no confiables con secretos o tareas sensibles, o hacerlo solo con extrema precaución
    • Seguir el principio de mínimo privilegio
    • Es indispensable conocer la guía oficial sobre permisos en GitHub Actions
  • Si ocurren vulnerabilidades similares, los administradores de la organización pueden desactivar Actions en bloque desde las políticas (se incluye una guía de configuración)

Conclusión

  • En un solo día, el investigador descubrió, reportó y ayudó a corregir una vulnerabilidad que podía poner en riesgo a todo el ecosistema de Nix
  • Esto dejó claro que se necesita extrema precaución al usar GitHub Actions, en especial pull_request_target
  • Agradece a Intrigus de KITCTF por ayudar con la investigación y a infinisil por responder con rapidez
  • Se recomienda a quienes tengan interés revisar el video de la presentación y los materiales adicionales
  • En general, se subraya la importancia de la seguridad en GitHub Actions y las lecciones prácticas que deja este caso

1 comentarios

 
GN⁺ 2025-10-17
Comentarios de Hacker News
  • Creo que pull_request_target es fundamentalmente inseguro y que GitHub debería eliminar esta función por completo. Normalmente se dice que para usar pull_request_target de forma segura basta con no ejecutar durante el trabajo código controlado desde la rama, pero en la práctica la superficie de ataque es mucho más amplia por cosas como inyección de argumentos o inclusión de archivos locales. En este momento, los únicos casos de uso legítimos son cosas como etiquetar automáticamente PRs de terceros o dejar comentarios automáticos. No creo que haga falta otorgar por defecto permisos de escritura al repositorio para esas tareas. GitHub debería poder emitir tokens limitados solo a ese tipo de trabajo. Por eso, en zizmor marco todos los usos de triggers peligrosos como pull_request_target; ver zizmor dangerous triggers

    • También estoy de acuerdo, pero sí hay un caso de uso cuando la organización no permite forks. Algunas herramientas manejan el merge fuera de github, y en esos casos aparecen PRs con merges no limpios, lo que impide que se dispare el workflow de pull_request. En esas situaciones, pull_request_target es prácticamente la única opción. Sería mejor que github ofreciera una configuración para correr workflows en PRs con merges no limpios, desactivada por defecto y pensada solo para cosas como linters. Hasta que exista eso, es una pena que por esta limitación no quede otra que usar pull_request_target. Por cierto, si usas una de esas herramientas externas, hacer un merge manual en github rompe todo el flujo; jamás hagas merge manual
    • En repos privados usamos pull_request_target por dos razones. Primero, porque el workflow siempre se ejecuta tomando como base main, así se puede bloquear código de pruebas no validado. Segundo, porque en el sub claim del JWT dentro del workflow se expone de forma decisiva job_workflow_ref, lo que permite un control de acceso fino en sistemas basados en OIDC
    • Según la explicación de GitHub, pull_request_target se ejecuta en el contexto base del PR, así que se supone que evita que código malicioso robe el repo o los secretos. Pero en realidad da un poco de risa cuando ves lo fácil que es filtrar secretos en la práctica
    • Esta superficie de ataque lleva casi un año sin resolverse. Vale la pena recordar el caso en que un paquete de python cayó por un nombre de rama malicioso que contenía código tipo shellshock. En ese momento también hubo un blog que resumía las variables vulnerables y los métodos de ataque desde la perspectiva de un pentester
  • Si el equipo de Nix hubiera adoptado builds reproducibles firmadas e independientes del firmado/revisión de commits, como propuse en mi RFC, este tipo de ataque de cadena de suministro de último tramo habría sido imposible. Al final, NixPkgs quiere que cualquiera pueda editar fácilmente y teme que cualquier intento serio de seguridad ahuyente a los voluntarios; su objetivo es enfocarse en una distro de hobby. Eso está bien, pero si quieren dejarle clara esa característica a la gente y proteger lo que tiene valor, entonces deberían dejar de usar o recomendar Nix en entornos críticos para la seguridad. Un sistema operativo que protege algo debería exigir una firma de hardware estricta de dos partes para cada cambio, y no depositar la confianza en una sola computadora o en una sola persona. Por eso hice Stagex enlace a Stagex enlace a Codeberg

    • Primero, aunque no es una postura oficial, dejo mi opinión como alguien que contribuye a mejorar la seguridad en nixpkgs. Supongo que el RFC al que te refieres es el RFC 0100 "Sign Commits" (enlace). Como se comentó en la discusión del RFC, el mayor obstáculo es que no hay soporte para firmar commits desde dispositivos móviles. nixpkgs no tiene margen para hacerse cargo también de desarrollar tooling móvil. Personalmente busco firmar commits y mejorar la provenance, pero desde el inicio se puede hacer push con commits sin firmar o con claves no confiables. En un proyecto centrado en seguridad como Stagex, ese tipo de capa de seguridad es obviamente necesaria. Pero nixpkgs tiene una filosofía de confianza distinta. Como no estoy de acuerdo con políticas de seguridad que hagan huir a los voluntarios, me gustaría ver estadísticas de cuánto se usarían realmente esas funciones en nixpkgs. nixpkgs no es solo una distro de hobby; también se usa bastante en grandes empresas, basta ver la lista de patrocinadores de NixCon 2025. Activar más funciones de seguridad es algo positivo, y en el futuro la situación podría cambiar. Pero ahora mismo creo que obligar a firmar commits en nixpkgs tiene demasiadas desventajas. Además, no recuerdo haber visto en el PR eso de "independent signed reproducible builds", y para una escala como la de nixpkgs sería enorme que un tercero montara esa infraestructura. Aun así, NixOS sí apunta a builds casi totalmente reproducibles enlace de estado, está bastante cerca, pero todavía no llega al 100%. En conclusión, los commits firmados sí contribuirían a una mejor seguridad, pero en nixpkgs también tendrían efectos negativos importantes, así que por ahora es difícil. Me da curiosidad el esquema de firma por hardware de dos partes de Stagex; estaría bueno que lo explicaras. Por último, reconozco la productividad y lo interesante del trabajo de Stagex, solo quería aclarar algunos malentendidos
    • Stagex es realmente impresionante, gracias por compartir el enlace
    • Solo quería dejar unas palabras de apoyo, es un proyecto realmente interesante
    • Recién hoy conocí Stagex, y fue el hallazgo más interesante de todo este hilo
    • Wow... me sorprende que ya hayas hecho algo que yo llevaba mucho tiempo queriendo hacer
  • Aunque llevamos décadas diseñando sistemas informáticos, me sigue pareciendo muy desconcertante que los workflows modernos todavía emitan bearer tokens, incluso de vida corta, a programas en los que se supone que deben confiar. Si el framework de GitHub Actions solo diera acceso a un socket Unix privilegiado o a ssh-agent, este tipo de vulnerabilidades sería mucho más difícil de explotar

    • Totalmente de acuerdo. Habría que pasar de bearer tokens a un esquema basado en firmas, y si expones directamente la clave privada en la práctica no es distinto de un bearer token. Un signing agent resuelve justamente ese papel. Aunque la API de github sea HTTP, con mutual TLS y un signing agent bastaría
    • El estándar SPIFFE cumple un papel parecido. Pero nadie lo usa; sinceramente creo que toda la industria, en la práctica, no se toma la seguridad realmente en serio
  • Las acciones de CI/CD para pull/merge requests son una verdadera pesadilla. Cuando un desarrollador escribe etapas de prueba o validación, normalmente piensa en algo como “mi código se ejecuta en el contexto de mi cuenta de github/gitlab”. Eso aplica a sus propios commits o a los de su equipo, pero en un PR el pipeline de CI/CD ejecuta código no confiable. Mantener siempre clara esa diferencia es difícil, y para cosas simples como correr pruebas o linters no pasa nada, pero en cuanto hay integración con infraestructura y hacen falta más permisos, el riesgo crece enseguida

    • El problema no es que CI/CD se dispare con PRs, sino que GitHub tiene dos triggers casi idénticos (pull_request y pull_request_target). Uno (por ejemplo pull_request) es casi seguro salvo que lo uses mal a propósito, y el otro (por ejemplo pull_request_target) casi no se puede usar de forma segura. Peor aún, GitHub hace que tareas comunes como poner etiquetas a PRs o dejar comentarios automáticos solo puedan hacerse desde el trigger peligroso (pull_request_target), así que todos terminan empujados a una opción inestable. Las funciones que ofrece GitHub Actions están estructuradas de una forma que invita al error
  • Con el tiempo me preocupa cada vez más el tema de los ataques a la cadena de suministro. No es solo una cuestión de “¿voy a perder el trabajo por esto?” o “apareció un nuevo vector de ataque en NixOS, CI/CD, Node, etc.”, sino una preocupación más filosófica. Cuanto más dependemos de estas cosas, más problemas inevitablemente tenemos que manejar. Incluso lo que debería ser cómodo ya está demasiado enredado: VSCode, Emacs, Nix, Vim, Firefox, JS, Node, todos estos plugins y paquetes de dependencias mezclados entre sí. Por eso, aunque me da vergüenza admitirlo, cada vez me acerco más a la extraña conclusión de que solo usando papel y tecnologías mínimas, realmente simples, puedo recuperar aunque sea una sensación de control o seguridad. Sé que no es racional, pero esta complejidad me agota cada vez más. Ya hasta siento que llegué a mi límite de complejidad

    • Emacs en sí es seguro y todas sus extensiones se pueden auditar manualmente. Pero si actualizas ciegamente todas las extensiones de forma automática, como una configuración de Nix, ahí sí hay problema. También se podría pensar en automatización que use LLMs para detectar y filtrar exploits obvios. La respuesta correcta para la validación a nivel empresa sería verificar formalmente todo con Coq, pero eso equivale a tirar a la basura el 99.999% del software existente
  • Si lees la advertencia en la página del manual de xargs, aparece la frase “xargs no puede usarse de forma segura”. Pero este problema de seguridad es distinto del caso aplicado aquí. En esta situación basta con añadir -- al final para evitarlo

  • La frase “xargs no puede usarse de forma segura” se malinterpreta muy seguido. Por ejemplo, si ejecutas cat "$HOME/changed_files" | xargs -r editorconfig-checker --, el problema específico del que se habla aquí sí se puede resolver

    • Pero eso es como intentar bloquear XSS agregando manualmente <div>{escapeHtml(value)}</div> a cada valor HTML. Si tienes que aplicar a mano la forma segura en todas partes, entonces el enfoque ya está mal desde el origen
    • Esa advertencia no aplica exactamente a esta situación, pero su semántica general sí es correcta. No todos los programas soportan un separador de argumentos como --, y la mayoría de los usos de xargs son vulnerables a inyección de argumentos. Dicho de otro modo, ejecutar cualquier comando siempre es intrínsecamente riesgoso. No es culpa de xargs en sí, sino de la realidad de reutilizar herramientas en múltiples contextos de privilegios
  • Ese artículo tiene una falla crítica con un alcance mucho mayor: en código de PR se puede cambiar el archivo OWNERS por un symlink para exponer archivos arbitrarios, como el archivo de credenciales de github actions. Como git permite commitear softlinks, casi cualquier workflow queda expuesto a este riesgo

    • Es cierto, pero si no recuerdo mal, al ejecutar pull_request_target las credenciales corresponden al repo objetivo, o sea, el repo al que se va a mergear. Si se ejecuta en pull_request, entonces las credenciales son del repo fuente controlado por el atacante
  • La única noticia “buena” es que OpenBSD y NetBSD todavía usan CVS para gestión de paquetes, así que esta vulnerabilidad no les afecta. De FreeBSD no estoy seguro. La seguridad, en cierto sentido, viene por el efecto de oscuridad. Aunque parece que esos proyectos también están considerando migrar a git, y OpenBSD probablemente avance con got(1)

    • Es cierto, pero esto no es una vulnerabilidad de git sino de github actions. Los BSD están indirectamente a salvo porque github no soporta CVS. Si usas git o github, pero no github actions, no te afecta
    • No es un problema de git, sino de github y específicamente de github actions
    • ¿No reciben contribuciones por correo electrónico? Entonces podrían ser incluso más vulnerables a ataques de suplantación, ¿no?