O gatilho que mudou tudo: lendo o diff de um workflow em busca de segredos expostos

Segurança em Nuvem Nível 3/4 ~5 min 29 de setembro de 2026

O desafio

O CI da Harbourline funcionou sem problemas por meses. Aí um mantenedor notou que o comentário de cobertura nunca aparecia em pull requests vindas de forks e corrigiu isso em uma linha, na revisão 13. O pipeline continua compilando, testando, comentando, e agora faz tudo isso para qualquer pessoa na internet que abra uma pull request. Três revisões do workflow estão aqui, mais o workflow de release e o package.json como contexto. Leia o que a revisão 13 mudou, descubra qual passo executa código escrito pelo contribuidor, e diga qual segredo esse passo entrega a ele.

O que você vai aprender

  • Explicar a diferença entre pull_request e pull_request_target
  • Rastrear qual job e qual step executa código controlado pelo contribuidor
  • Determinar quais segredos são acessíveis a partir de um step específico
  • Reconhecer scripts de lifecycle do npm como um sink de execução no CI
  • Usar os limites entre jobs e as condições para incluir ou descartar segredos na análise

Habilidades testadas

Revisão de configuração de CI/CDAnálise de limites de confiançaRaciocínio sobre supply chain

Pré-requisitos

  • Leitura de YAML
  • O que um pipeline de CI faz em uma pull request

Como funciona

Um sistema de CI que compila pull requests precisa responder uma pergunta antes de qualquer outra coisa: de quem é esse código, e o que ele pode alcançar. O pull_request responde de forma conservadora. O job roda no contexto do fork, os segredos ficam de fora, e o token automático é somente leitura, então o código de um estranho executa mas não encontra nada que valha a pena roubar.

O pull_request_target responde de outra forma. O job roda no contexto do repositório base, com todo o cofre de segredos e um token com permissão de escrita, que é a única forma de um workflow etiquetar, comentar ou triar uma contribuição externa. A segurança dessa troca depende inteiramente de uma suposição: o job nunca executa nada que o contribuidor escreveu. Por padrão, ele faz checkout do branch base justamente para manter isso verdadeiro.

No momento em que alguém adiciona ref: github.event.pull_request.head.sha para fazer o build realmente testar a mudança, essa suposição deixa de existir e as duas metades se combinam em execução remota de código com credenciais de produção. Em um projeto Node não existe nem um passo de build para subverter: o npm ci executa os lifecycle scripts do próprio package.json do contribuidor antes de qualquer um dos seus comandos.

Erros comuns

  • Responder GITHUB_TOKEN. Ele é elevado sob esse gatilho, mas é referenciado no job comment, que nunca faz checkout do código do contribuidor.
  • Responder CODECOV_TOKEN. Mesmo job do passo de comentário, mesmo motivo.
  • Responder SLACK_WEBHOOK. Seu passo é protegido por github.event_name == 'push', e essa execução é um evento de pull request.
  • Responder GPG_SIGNING_KEY. Isso está em release.yml, que só é disparado por um push de tag.
  • Culpar a r12. A r12 já reutilizava o token de publicação, o que é descuidado, mas sob pull_request nenhum fork conseguiria vê-lo. A exposição começa na r13.

Como se proteger

Mantenha o contexto privilegiado e o código não confiável em jobs diferentes.

  • Compile e teste em pull_request, sem segredos. Se um passo privilegiado posterior for necessário, execute-o em workflow_run sobre o artefato já armazenado, nunca sobre um checkout novo do branch do contribuidor.
  • Se o pull_request_target for genuinamente necessário, não faça checkout do head ref de jeito nenhum. Um workflow que apenas etiqueta ou comenta não precisa do código.
  • Limite as credenciais ao job que precisa delas. Um token de registro somente leitura para instalações e um token de publicação separado que exista só no workflow de release teriam tornado esse incidente sobrevivível.
  • Execute as instalações com os lifecycle scripts desabilitados, por exemplo npm ci --ignore-scripts, para que um package.json não confiável não consiga executar antes dos seus próprios comandos.
  • Exija um environment com aprovação manual para qualquer job que detenha uma credencial de publicação.

Solução completa

Membros Pro e Max desbloqueiam o passo a passo completo.

Assinar Pro

Estatísticas da comunidade

120 resoluções
84% taxa de sucesso
Malekith Primeiro sangue

Hacks de hoje relacionados

30.000+ Hackers Labs reais Grátis
Comece Grátis ou resolva o hack de hoje, sem conta