O que é Poisoned Pipeline Execution (PPE)?
A execução de pipelines envenenados (PPE), um risco de segurança de CI/CD da OWASP, é um vetor de ataque que abusa das permissões de acesso a um sistema de gerenciamento de código-fonte (SCM) com a intenção de fazer com que um pipeline de CI execute comandos maliciosos. Embora os invasores de PPE não tenham acesso ao ambiente de compilação, eles obtiveram acesso ao SCM, o que lhes permite injetar código mal-intencionado na configuração do pipeline de compilação para manipular o processo de compilação.
CICD-SEC-4: Explicação da execução do oleoduto envenenado
A execução de pipelines envenenados (PPE), listada como CICD-SEC-4 nos 10 principais riscos de segurança de CI/CD da OWASP, representa uma estratégia de ataque sofisticada que visa à integração contínua e aos sistemas de implantação contínua (CI/CD).
Os clientes podem ter uma variedade de opções disponíveis:
Na estratégia PPE, os invasores executam códigos mal-intencionados na parte de CI do pipelines de CI/CD, ignorando a necessidade de acesso direto ao sistema de CI/CD. O método envolve a manipulação de permissões em um repositório de gerenciamento de código-fonte (SCM). Ao alterar os arquivos de configuração de CI ou outros arquivos dos quais o trabalho do pipeline de CI depende, os invasores injetam comandos mal-intencionados, envenenando efetivamente o pipeline de CI e permitindo a execução não autorizada de códigos.
Ataques bem-sucedidos de PPE podem permitir uma ampla gama de operações, todas executadas no contexto da identidade do pipeline. As operações mal-intencionadas podem incluir o acesso a segredos disponíveis para o trabalho de CI, a obtenção de acesso a ativos externos para os quais o nó de trabalho tem permissões, o envio de códigos e artefatos aparentemente legítimos pelo pipeline e o acesso a hosts e ativos adicionais na rede ou no ambiente do nó de trabalho.
Devido ao seu impacto crítico, à baixa detectabilidade e à existência de várias técnicas de exploração, o ataque PPE representa uma ameaça generalizada. Para as equipes de segurança, engenheiros e red team (equipe vermelha), compreender o EPI e suas contramedidas é fundamental para a segurança de CI/CD
Definição de execução de pipeline
No contexto da integração contínua (CI), o fluxo de execução do pipeline refere-se à sequência de operações definidas pelo arquivo de configuração de CI hospedado no repositório que o pipeline constrói. Esse arquivo descreve a ordem dos trabalhos executados, além de detalhar as configurações e as condições do ambiente de compilação que afetam o fluxo. Quando acionado, o trabalho do pipeline extrai o código da fonte escolhida (por exemplo, commit/branch) e executa os comandos especificados no arquivo de configuração de CI em relação a esse código.
Os comandos dentro do pipeline são invocados diretamente pelo arquivo de configuração de CI ou indiretamente por um script, teste de código ou linter que reside em um arquivo separado referenciado a partir do arquivo de configuração de CI. Os arquivos de configuração de CI normalmente têm nomes e formatos consistentes, como Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) e os arquivos YAML do GitHub Actions localizados em .github/workflows.
Os invasores podem explorar a capacidade de manipular os comandos executados pelo pipeline, direta ou indiretamente, e podem ser explorados por invasores para executar códigos mal-intencionados no CI.
Como ocorre a exploração do CICD-SEC-4
Para que um ataque de EPI seja bem-sucedido, vários critérios devem ser atendidos:
- O invasor deve obter permissões em um repositório SCM. Isso pode ser feito por meio de credenciais de usuário, tokens de acesso, chaves SSH, tokens OAuth ou outros métodos. Em alguns casos, o acesso anônimo a um repositório público pode ser suficiente.
- As alterações no repositório em questão devem acionar um pipeline de CI sem aprovações ou revisões adicionais. Isso pode ser feito por meio de pushs diretos para ramificações remotas ou por meio de alterações sugeridas por meio de um pull request de uma ramificação ou bifurcação remota.
- As permissões obtidas pelo invasor devem permitir o acionamento dos eventos que fazem com que o pipeline seja executado.
- Os arquivos que o invasor pode alterar devem definir os comandos que são executados (direta ou indiretamente) pelo pipeline.
- O nó do pipeline deve ter acesso a recursos não públicos, como segredos, outros nós ou recursos de computação.
Os pipelines que executam códigos não revisados, como aqueles acionados por solicitações pull ou commits em ramificações arbitrárias do repositório, são mais suscetíveis à PPE. Quando um invasor consegue executar um código mal-intencionado no pipeline de CI, ele pode realizar operações mal-intencionadas no contexto da identidade do pipeline.
Três tipos de execução de dutos envenenados
A execução de pipeline envenenado se manifesta de três formas distintas: PPE direto (D-PPE), PPE indireto (I-PPE) e PPE público (3PE).
EPI direto
Em um cenário de PPE direto, os invasores modificam o arquivo de configuração de CI em um repositório ao qual têm acesso, seja enviando a alteração diretamente para um branch remoto desprotegido no repositório ou enviando um pull request com a alteração de um branch ou fork. A execução do pipeline é acionada pelos eventos de solicitação push ou pull, conforme definido pelos comandos no arquivo de configuração de CI modificado, o que resulta na execução dos comandos mal-intencionados no nó de compilação quando o pipeline de compilação é acionado.

Figura 1: Fluxo de ataque de execução de pipeline envenenado direto
O exemplo de ataque D-PPE ilustrado na figura 1 ocorre na seguinte sucessão de etapas:
- Um adversário inicia uma nova ramificação remota no repositório, alterando o arquivo de configuração do pipeline com instruções prejudiciais para recuperar as credenciais da AWS armazenadas na organização do GitHub e transmiti-las a um servidor externo sob o controle do invasor.
- O envio de código ativa um pipeline que extrai o código, inclusive o arquivo de configuração do pipeline mal-intencionado, do repositório.
- O pipeline opera de acordo com o arquivo de configuração, agora contaminado pelo invasor. As instruções maliciosas comandam as credenciais do AWS, armazenadas como segredos de repositório, para serem carregadas na memória.
- Seguindo as instruções do invasor, o pipeline executa a tarefa de transmitir as credenciais do AWS para um servidor sob o controle do invasor.
- De posse das credenciais roubadas, o invasor ganha a capacidade de se infiltrar no ambiente de produção.
EPI indireto
O EPI indireto ocorre quando a possibilidade de EPI-D não está disponível para um adversário com acesso a um repositório de SCM:
- Se o pipeline estiver configurado para extrair o arquivo de configuração de CI de uma ramificação separada e protegida no mesmo repositório.
- Se o arquivo de configuração de CI for armazenado em um repositório separado do código-fonte, sem a opção de um usuário editá-lo diretamente.
- Se a compilação de CI for definida no próprio sistema de CI, em vez de em um arquivo armazenado no código-fonte.
Nesses cenários, o invasor ainda pode envenenar o pipeline injetando código mal-intencionado em arquivos referenciados pelo arquivo de configuração do pipeline, como scripts referenciados no arquivo de configuração do pipeline, testes de código ou ferramentas automáticas, como linters e scanners de segurança usados no CI. Por exemplo:
- O utilitário make executa os comandos definidos no arquivo Makefile.
- Scripts referenciados no arquivo de configuração do pipeline, que são armazenados no mesmo repositório que o próprio código-fonte (por exemplo, python myscript.py - onde myscript.py seria manipulado pelo invasor).
- Testes de código: Os frameworks de teste executados no código do aplicativo dentro do processo de compilação dependem de arquivos dedicados, armazenados no mesmo repositório que o código-fonte. Os atacantes que conseguem manipular o código responsável pelo teste podem executar comandos maliciosos internos à compilação.
- Ferramentas automáticas: Os linters e scanners de segurança usados na CI geralmente dependem de um arquivo de configuração residente no repositório que normalmente carrega e executa código externo a partir de um local definido interno ao arquivo de configuração.
Em vez de envenenar o pipeline por meio de PPE direto, o invasor que lança um ataque de PPE indireto injeta código mal-intencionado em arquivos referenciados pelo arquivo de configuração. O código malicioso é finalmente executado no nó do pipeline e executa os comandos declarados nos arquivos.

Figura 2: Fluxo de ataque indireto de execução de pipeline envenenado
Nesse exemplo de ataque I-PPE, a cadeia de eventos se desenrola da seguinte forma:
- Um invasor cria uma solicitação pull no repositório, anexando comandos maliciosos ao arquivo Makefile.
- Como o pipeline está configurado para ser acionado em qualquer PR contra o repositório, o pipeline do Jenkins é acionado, obtendo o código do repositório, incluindo o Makefile malicioso.
- O pipeline é executado com base no arquivo de configuração armazenado na ramificação principal. Ele chega ao estágio de compilação e carrega as credenciais do AWS em variáveis de ambiente, conforme definido no arquivo original do Jenkins. Em seguida, ele executa o comando make build, que executa o comando malicioso que foi adicionado ao Makefile.
- A função de compilação maliciosa definida no Makefile é executada, enviando as credenciais do AWS para um servidor controlado pelo invasor.
- O invasor pode então usar as credenciais roubadas para acessar o ambiente de produção do AWS.
EPIs públicos
O PPE público é um tipo de ataque de PPE executado por atacantes anônimos na Internet. Os repositórios públicos geralmente permitem que qualquer usuário contribua, normalmente criando solicitações pull. Se o pipeline de CI de um repositório público executar códigos não revisados sugeridos por usuários anônimos, ele estará suscetível a um ataque de PPE público. O PPE público também pode expor ativos internos, como segredos de projetos privados, nos casos em que o pipeline do repositório público vulnerável é executado na mesma instância de CI que os privados.
Importância da execução de pipelines seguros de CI/CD
A execução de código malicioso não revisado no CI por meio de um ataque bem-sucedido de PPE fornece aos invasores o mesmo nível de acesso e capacidade que o trabalho de compilação:
- Acesso aos segredos disponíveis para o trabalho de CI, como segredos injetados como variáveis de ambiente ou segredos adicionais armazenados no CI. Por serem responsáveis pela criação de código e implantação de artefatos, os sistemas de CI/CD normalmente contêm dezenas de credenciais e tokens de alto valor, como para um provedor de nuvem, para registros de artefatos e para o próprio SCM.
- Acesso a ativos externos para os quais o nó de trabalho tem permissões, como arquivos armazenados no sistema de arquivos do nó ou credenciais para um ambiente de nuvem acessível por meio do host subjacente.
- Capacidade de enviar código e artefatos mais adiante no pipeline, sob o disfarce de código legítimo criado pelo processo de compilação.
- Capacidade de acessar hosts e ativos adicionais na rede/ambiente do nó de trabalho.
Mas as organizações podem proteger seus produtos de software e sua infraestrutura com um pipeline de execução seguro que garanta que todo o código compilado, testado e implantado seja legítimo e não adulterado.
Riscos associados à execução de dutos envenenados
As implicações do EPI podem ser graves, variando de acesso não autorizado a dados, comprometimento da integridade do software, interrupções do sistema, violações de dados ou até mesmo um controle total do sistema. Esses riscos representam ameaças significativas tanto para a empresa quanto para seus clientes, ressaltando a gravidade do EPI.

Figura 3: Impacto downstream de um pipeline de CI envenenado
Na operação de comprometimento da cadeia de suprimentos em oito etapas vista na figura 3, o invasor obtém acesso ao pipeline de CI e envenena os componentes do aplicativo SaaS. Por meio do componente envenenado, o invasor cria uma funcionalidade de backdoor no aplicativo e envia os plug-ins envenenados para clientes downstream. Como as organizações downstream provavelmente percebem o pacote envenenado como legítimo, elas o incorporam em sua infraestrutura na nuvem ou no local.
A partir de um pipeline de CI envenenado, o invasor obtém danos colaterais exponenciais, tendo criado um acesso de backdoor a inúmeras organizações. Esse foi o caso do ataque doSolarWinds.
LEIA MAIS: Anatomia de um ataque a pipelines de CI/CD
Como evitar a execução de pipelines envenenados
A prevenção e a mitigação do vetor de ataque PPE envolvem várias medidas que abrangem os sistemas SCM e CI:
- Garantir que os pipelines que executam códigos não revisados sejam executados em nós isolados e não expostos a segredos e ambientes sensíveis.
- Avaliar a necessidade de acionar pipelines em repositórios públicos de colaboradores externos. Quando possível, evite executar pipelines originados de bifurcações e considere adicionar controles, como requisitos de aprovação manual para a execução do pipeline.
- Para pipelines confidenciais, por exemplo, aqueles que são expostos a segredos, certifique-se de que cada ramificação configurada para acionar um pipeline no sistema de CI tenha uma regra de proteção de ramificação de correlação no SCM.
- Para evitar a manipulação do arquivo de configuração de CI para executar códigos mal-intencionados no pipeline, cada arquivo de configuração de CI deve ser revisado antes da execução do pipeline. Como alternativa, o arquivo de configuração de CI pode ser gerenciado em uma ramificação remota, separada da ramificação que contém o código que está sendo criado no pipeline. A filial remota deve ser configurada como protegida.
- Remova as permissões concedidas no repositório SCM de usuários que não precisam delas.
- Cada pipeline deve ter acesso apenas às credenciais necessárias para cumprir sua finalidade. As credenciais devem ter os privilégios mínimos necessários.