Auditando Workflows do GitHub para Riscos de Segurança
Ataques à cadeia de suprimentos contra o GitHub Actions deixaram de ser teóricos para se tornarem rotineiros. O comprometimento do tj-actions/changed-files em março de 2025 demonstrou com que rapidez uma única action envenenada pode vazar segredos em milhares de repositórios. Um ano depois, o padrão se repetiu com o incidente do Trivy-action, no qual atacantes forçaram o push de código malicioso em 76 dos 77 tags de versão.
Se você já possui workflows em produção, este checklist ajuda a identificar as vulnerabilidades mais comuns sem a necessidade de redesenhar todo o seu pipeline.
Principais Conclusões
- Defina
permissions: {}no nível do workflow e conceda apenas os escopos mínimos necessários para cada job. - Nunca interpole valores de
${{ github.event.* }}diretamente em comandos shell — passe-os por variáveis de ambiente. - Fixe actions de terceiros a SHAs de commit completos e evite combinar
pull_request_targetcom checkouts de código de forks. - Substitua credenciais estáticas de nuvem por OIDC e impeça que runners auto-hospedados executem código não confiável em repositórios públicos.
Verifique Primeiro as Permissões do GITHUB_TOKEN
Abra qualquer arquivo de workflow e procure o bloco permissions no nível superior. Se ele estiver ausente, o padrão da sua organização será aplicado — e organizações criadas antes de fevereiro de 2023 frequentemente têm como padrão permissões de leitura e escrita.
A correção é direta:
permissions: {} # deny all at workflow level
jobs:
build:
permissions:
contents: read # grant only what the job needs
Definir permissions: {} no nível do workflow obriga você a declarar exatamente o que cada job precisa. Um job que apenas lê código nunca deveria ter um GITHUB_TOKEN com acesso de escrita ao seu repositório.
Identifique Entradas Não Confiáveis em Comandos Shell
Pesquise nos seus arquivos de workflow por ${{ github.event dentro de blocos run:. Este é o padrão mais comum de injeção de scripts:
# Arriscado: o atacante controla o título do PR
- run: echo "Checking ${{ github.event.pull_request.title }}"
A alternativa segura é passar valores não confiáveis por meio de uma variável de ambiente intermediária:
- name: Check PR title
env:
TITLE: ${{ github.event.pull_request.title }}
run: echo "Checking $TITLE"
O valor é passado via ambiente em vez de ser interpolado diretamente no script shell, de modo que metacaracteres shell presentes na entrada não conseguem escapar e executar comandos. Fique atento também a escritas em GITHUB_ENV e GITHUB_PATH em steps que manipulam conteúdo controlado pelo usuário — atacantes podem utilizá-los para injetar variáveis de ambiente ou binários maliciosos em steps posteriores.
Audite o Uso de pull_request_target
O pull_request_target é executado com acesso aos segredos da branch base, o que o torna útil para workflows que precisam comentar em PRs de forks. O risco não está no trigger em si — está em combiná-lo com um checkout do código do fork:
# Combinação perigosa
on: pull_request_target
jobs:
test:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }} # executa código do atacante
- run: npm test # com acesso aos seus segredos
Se você utilizar pull_request_target, certifique-se de que nenhum step execute código da branch do PR. O GitHub mitigou parcialmente esse problema no final de 2025, mas o trigger continua sendo de alto risco quando combinado com checkouts de forks.
Discover how at OpenReplay.com.
Revise a Fixação de Actions de Terceiros
O comprometimento do tj-actions/changed-files foi possível porque equipes referenciavam tags mutáveis como @v35. Os valores das tags podem ser silenciosamente reescritos. A fixação por SHA de commit completo previne isso:
# Vulnerável
- uses: tj-actions/changed-files@v35
# Seguro
- uses: tj-actions/changed-files@d6babd6899969df1a11d14c368283ea4436bca78
O GitHub agora oferece políticas no nível da organização para impor a fixação por SHA e reprovar workflows que utilizem actions não fixadas. Verifique em Settings → Actions → General no nível da organização. A fixação por si só não é suficiente — considere também um período de carência de 7 a 14 dias antes de adotar novas versões de actions, já que a maioria dos comprometimentos na cadeia de suprimentos é detectada dentro de uma semana.
Avalie a Exposição de Runners Auto-Hospedados
Runners auto-hospedados são persistentes por padrão. Um workflow comprometido pode instalar backdoors que sobrevivem entre jobs. A questão crítica é se algum repositório público utiliza seus runners auto-hospedados — caso positivo, qualquer colaborador pode submeter um PR que execute código arbitrário na sua infraestrutura.
Verifique seus grupos de runners em Settings → Actions → Runners e confirme que repositórios públicos estão excluídos. Para cargas de trabalho sensíveis, prefira runners just-in-time (JIT) que são destruídos após cada job.
Substitua Credenciais Estáticas de Nuvem por OIDC
Se seus workflows se autenticam na AWS, Azure ou GCP usando credenciais estáticas armazenadas como segredos, essas credenciais ficam expostas a todas as actions e steps daquele job. O OpenID Connect (OIDC) elimina esse problema ao emitir tokens de curta duração com escopo por job em tempo de execução. Sem segredo para roubar, sem credencial para rotacionar manualmente.
Verificações Adicionais que Vale a Pena Realizar
- Manipulação de artefatos: Defina
persist-credentials: falsenoactions/checkouta menos que steps posteriores precisem explicitamente do token. Isso impede que o token de checkout permaneça disponível na configuração local do Git para steps posteriores do workflow. - Proteções de ambiente: Segredos de implantação devem residir em GitHub Environments com revisores obrigatórios, e não como segredos simples do repositório.
- Atestações de artefatos: Para pacotes publicados, as atestações de artefatos do GitHub fornecem um vínculo verificável entre uma build e seu workflow de origem.
- OpenSSF Scorecards: A action do Scorecards pode ser configurada para executar verificações automatizadas de permissões de token, actions fixadas e injeção de scripts — útil para detectar regressões automaticamente.
Por Onde Começar
Execute uma busca em .github/workflows/ pelos seguintes padrões: blocos permissions ausentes ou definidos como write-all, ${{ dentro de steps run:, triggers pull_request_target e referências a actions sem um SHA completo. Essas quatro verificações revelarão os problemas de maior risco na maioria dos repositórios sem exigir nenhuma ferramenta adicional.
Conclusão
Proteger o GitHub Actions não requer uma reescrita completa do pipeline — a maioria dos incidentes reais pode ser rastreada a um pequeno conjunto de erros recorrentes: escopos de token excessivamente amplos, interpolação insegura de entradas não confiáveis, referências mutáveis a actions e runners expostos a código não confiável. Percorrer as verificações acima fornece uma linha de base defensável. Combine essa linha de base com varredura automatizada por meio do OpenSSF Scorecards ou ferramentas similares, e você detectará regressões antes que cheguem à produção.
Perguntas Frequentes
A busca de código do GitHub suporta consultas em toda a organização. Pesquise por termos como 'pull_request_target', 'permissions: write-all' ou 'github.event.pull_request.title' com escopo para path:.github/workflows. Para análises mais aprofundadas, ferramentas como Octoscan, zizmor e a action do OpenSSF Scorecards podem varrer repositórios inteiros e gerar relatórios sobre escopos de token, actions não fixadas e pontos de injeção automaticamente.
Não, mas torna as atualizações explícitas. Você decide quando atualizar o SHA após revisar as diferenças entre as versões. Ferramentas como Dependabot e Renovate podem abrir pull requests que atualizam SHAs fixados automaticamente, oferecendo a segurança da fixação sem o ônus de manutenção. Um atraso de 7 a 14 dias antes de mesclar essas atualizações reduz ainda mais a exposição a versões recentemente comprometidas.
Para AWS, Azure, GCP e a maioria dos principais provedores, sim. Tokens OIDC têm curta duração, são limitados a uma execução específica do workflow e não podem ser exfiltrados para uso posterior. A configuração requer o estabelecimento de uma relação de confiança no seu provedor de nuvem, mas elimina o ônus de rotação e limita o raio de impacto caso um workflow seja comprometido. Segredos estáticos permanecem uma alternativa válida apenas quando o OIDC não é suportado.
O trigger pull_request é executado no contexto do fork e não tem acesso aos segredos do repositório base, tornando-o seguro para executar testes em código não confiável. O trigger pull_request_target é executado no contexto do repositório base com acesso a segredos, destinado a tarefas como rotular PRs. A combinação perigosa a evitar é usar pull_request_target junto com um checkout do código do fork.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.