Sumário Executivo
Em 3 de março de 2026, a Xygeni detectou atividade suspeita afetando o repositório usado para publicar a ação do GitHub xygeni/xygeni-action. A atividade teve origem em credenciais comprometidas associadas a um token de mantenedor e a um aplicativo do GitHub instalado no repositório.
Durante o incidente, um invasor tentou introduzir código malicioso no repositório por meio de uma série de pull requestsEssas tentativas foram bloqueadas pelas regras de proteção de ramificação existentes, impedindo que o código fosse mesclado à ramificação principal do repositório.
No entanto, o atacante explorou posteriormente um vetor diferente, movendo a tag v5 mutável para referenciar um elemento malicioso. commit criado durante o pull request tentativas. Os fluxos de trabalho que fazem referência a xygeni/xygeni-action@v5 poderiam, portanto, recuperar o código comprometido sem qualquer alteração visível em suas definições de fluxo de trabalho.
A manipulação da etiqueta foi identificada em 9 de março, após relatos da comunidade. A etiqueta comprometida foi imediatamente removida e os procedimentos de resposta a incidentes foram iniciados.
Nossa investigação determinou o seguinte:
- Nenhum código malicioso foi incorporado à ramificação principal do repositório.
- Não há Não há evidências de comprometimento da plataforma SaaS da Xygeni. ou dados do cliente.
- A janela de exposição foi limitada a fluxos de trabalho que faziam referência a xygeni/xygeni-action@v5 entre 3 e 9 de março de 2026.
- A etiqueta comprometida foi removida permanentemente e não será recriada.
Após a descoberta da manipulação de tags, a Xygeni implementou diversas melhorias de segurança em seus repositórios e processos de lançamento, incluindo:
- Remoção da etiqueta comprometida e orientações de migração para Referências fixadas por SHA.
- Execução de liberação imutabilidade entre repositórios.
- Reforço das permissões do repositório e do acesso dos colaboradores.
- Obrigatório assinado criptograficamente commits para os responsáveis pela manutenção.
- Restrição de acesso de escrita a um conjunto limitado de mantenedores e administradores.
Publicamos este relatório para dar transparência ao incidente, compartilhar as lições aprendidas e ajudar a fortalecer as práticas de segurança em todo o ecossistema do GitHub Actions.
Embora o ataque tenha explorado uma vulnerabilidade conhecida do GitHub Actions relacionada a tags mutáveis, o incidente também destaca a importância da proteção abrangente do repositório, do gerenciamento rigoroso de credenciais e da defesa em profundidade em toda a infraestrutura. CI/CD sistemas.
Transparência e colaboração são essenciais para melhorar a resiliência da cadeia de suprimentos de software.
Visão geral do incidente
Este relatório documenta a investigação de um incidente de segurança que afetou o público. xygeni/ação xygeni Repositório de ações do GitHub.
Em 3 de março de 2026, um invasor usou credenciais comprometidas associadas à automação do repositório para introduzir código malicioso por meio de uma série de pull request tentativas. A carga útil continha um implante de comando e controle disfarçado de telemetria de scanner.
As regras de proteção de ramificação do repositório impediram com sucesso que o código malicioso fosse mesclado ao repositório. filial principalNo entanto, o atacante posteriormente manipulou o mutável. v5 etiqueta, redirecionando-o para um commit contendo a carga útil injetada. Como muitos fluxos de trabalho fazem referência ao GitHub Actions usando tags de versão principal, isso envenenamento por etiquetas fluxos de trabalho subsequentes permitidos que faziam referência a xygeni/xygeni-action@v5 para recuperar o código comprometido sem qualquer alteração visível na configuração do fluxo de trabalho.
Como provedor de software supply chain security da compressãoA Xygeni opera infraestrutura que se integra diretamente ao desenvolvimento. pipelineareia CI/CD ambientes. Projetos nesse espaço são alvos frequentes de ataques que visam comprometer ferramentas de desenvolvimento amplamente utilizadas para atingir ambientes subsequentes.
Timeline
Fase 1: O Malicioso Pull Requests (3 de março, 10:22–10:50 UTC)
Às 10h22 UTC do dia 3 de março de 2026, um atacante iniciou um ataque rápido e coordenado ao repositório xygeni-action, utilizando duas identidades comprometidas: o token de acesso pessoal (PAT) de um mantenedor e a chave privada de um aplicativo do GitHub (xygeni-onboarding-app-dev). Nos 28 minutos seguintes, três pull requests Foram criadas e fechadas, cada uma injetando código shell ofuscado no arquivo action.yml.
A abordagem do atacante foi metódica e adaptativa:
- PR # 46 (10:22–10:29 UTC): Criado pelo mantenedor comprometido PAT sob o ramo recurso/telemetria de scannerO atacante tentou realizar o merge, mas foi bloqueado pelas regras de proteção de branch. O PR foi fechado sem que o merge fosse realizado.
- Reconhecimento (10:39–10:40 UTC): O atacante testou o acesso do aplicativo GitHub criando e excluindo imediatamente uma ramificação chamada acesso ao aplicativo de testeIsso confirmou que o aplicativo tinha permissão de gravação no repositório.
- PR # 47 (10:41–10:44 UTC): Uma segunda tentativa usando o PAT do mantenedor, agora em um branch renomeado. melhoria/telemetria do scannerMais uma vez bloqueado pela proteção de branch. O atacante tentou usar o aplicativo GitHub para aprovar o PR — burlando a exigência de dois revisores ao fazer com que uma identidade comprometida aprovasse o trabalho da outra. Isso também falhou.
- PR # 48 (10:45–10:49 UTC): Os papéis foram invertidos — o aplicativo GitHub criou o PR (enviando) commit 4bf1d4e), e o mantenedor PAT submeteu a revisão de aprovação. Esta também foi rejeitada pela proteção de ramificação.
Nenhuma das solicitações de pull request (PRs) chegou à branch principal. Nossas regras de proteção de branch se mantiveram: a exigência de duas aprovações, a regra de que o push mais recente deve ser aprovado por alguém diferente do responsável pelo push e a restrição de ignorar essas configurações, tudo isso combinado bloqueando todas as tentativas de merge.
Nossa equipe detectou a atividade anômala durante a revisão de rotina de solicitações de pull request e iniciou uma resposta a incidentes às 12h21 UTC — menos de duas horas após a primeira solicitação de pull request maliciosa. A resposta incluiu a remoção de fluxos de trabalho, a preservação do código malicioso para análise forense e a segurança do repositório.
Fase 2: O Envenenamento por Etiquetas
Embora a proteção de ramificação tenha impedido com sucesso que o código malicioso chegasse à ramificação principal, o invasor explorou um vetor diferente. Usando as credenciais comprometidas do aplicativo GitHub, o invasor moveu a tag v5 mutável para apontar para... commit 4bf1d4e — o malicioso commit do PR #48 que ainda existia no armazenamento de objetos do repositório mesmo após a exclusão do branch do PR.
É importante ressaltar que essa manipulação de tags não ocorreu imediatamente após os PRs. Os registros de atividade do repositório do GitHub não mostram eventos de push forçado de tags da mesma forma que operações de branch, o que limita a capacidade de reconstruir o timestamp exato da modificação da tag. No entanto, a tag foi confirmada como envenenada quando a comunidade alertou sobre o problema em 9 de março.
Esta é a principal conclusão: as regras de proteção de ramificações não protegem as tags. commit O arquivo contendo a porta dos fundos existia no banco de dados de objetos Git do repositório, e a tag v5 — referenciada pelos fluxos de trabalho subsequentes — podia ser redirecionada silenciosamente para ele. Qualquer fluxo de trabalho que utilizasse xygeni/xygeni-action@v5 baixaria o código comprometido, sem que nenhuma alteração fosse visível na branch principal ou nos arquivos de fluxo de trabalho dos repositórios que o utilizavam.
Causa raiz
Nossa investigação concluiu que a causa principal foi o comprometimento da chave privada de um aplicativo do GitHub (xygeni-onboarding-app-dev) que havia sido instalado no repositório.
Este aplicativo do GitHub foi originalmente criado para testar a experiência de integração na plataforma da Xygeni. Ele tinha permissões de gravação no repositório — permissões que, em retrospectiva, eram mais amplas do que o necessário para sua finalidade.
Com a chave privada de um aplicativo GitHub, um invasor pode:
- Gere tokens de instalação de curta duração conforme necessário.
- Criar e aprovar pull requests
- Empurrar commitvia Git sobre HTTPS
- Remover etiquetas — a ação crucial que tornou este incidente impactante.
O atacante usou tanto a PAT (Personal Access Token) do mantenedor comprometida quanto as credenciais do aplicativo GitHub em uma tentativa coordenada: quando uma identidade sozinha não conseguiu burlar as proteções, as duas identidades foram usadas em conjunto — uma para criar e a outra para aprovar.
O vetor exato pelo qual a chave privada foi exfiltrada ainda está sob investigação. Chaves privadas de aplicativos do GitHub (arquivos .pem) podem vazar por meio de fluxos de trabalho mal configurados, máquinas de desenvolvedores comprometidas ou armazenamento de segredos inseguro.
Comportamento malicioso da carga útil
O código injetado era um implante compacto de comando e controle. Ele foi projetado para funcionar silenciosamente ao lado do scanner legítimo, executando-se em três fases:
- Registro. O implante contata um servidor C2 em 91.214.78.178 (disfarçado via DNS curinga nip.io como security-verify.91.214.78.178.nip.io), enviando o nome do host, o nome de usuário e a versão do sistema operacional do executor.
- Loop de sondagem. Durante 180 segundos (dentro dos tempos limite típicos de tarefas de CI), o implante consulta o servidor C2 a cada 2 a 7 segundos em busca de comandos para executar.
- Execução de comandos. Quaisquer comandos recebidos são executados via eval, com a saída comprimida (zlib), codificada em base64 e exfiltrada de volta para o servidor C2.
Silenciosamente omitidos, os nomes das variáveis foram deliberadamente concisos e o intervalo de amostragem foi aleatorizado para evitar a detecção de padrões de tráfego.
Se o implante fosse executado em um executor de CI, o atacante teria tido acesso ao GITHUB_TOKEN, segredos do repositório, código-fonte e, potencialmente, chaves de assinatura de artefatos. O implante poderia ter permitido a execução de comandos em um executor de CI se executado dentro de um fluxo de trabalho que referenciasse a tag comprometida.
Neste momento, temos Não há evidências de que o payload tenha sido executado em qualquer ambiente de CI do cliente. ou que segredos foram exfiltrados por meio da ação.
Infraestrutura C2
O servidor C2 estava hospedado na Partner Hosting LTD (AS215826), registrada em 71-75 Shelton Street, Covent Garden, Londres — um endereço de escritório virtual comumente utilizado. A infraestrutura havia sido provisionada recentemente (a sub-rede foi modificada pela última vez apenas 5 dias antes do ataque) e o IP já estava associado a RATs, infostealers e loaders em feeds de inteligência de ameaças. A infraestrutura e as ferramentas indicam um atacante capaz e familiarizado com CI/CD ambientes.
Avaliação de exposição
Principais observações
Etiquetas mutáveis são um risco conhecido — mas a inércia é poderosa.
O ecossistema do GitHub Actions tem um problema bem documentado: tags mutáveis. Quando os usuários fazem referência a `action@v5`, eles confiam que a tag aponta para um código seguro. Mas as tags podem ser alteradas à força por qualquer pessoa com permissão de escrita. Este é o principal vetor de ataque à cadeia de suprimentos do GitHub Actions, e nós sabíamos disso — mesmo assim, nossa documentação ainda direcionava os usuários para `@v5`.
A proteção de ramificação não é proteção de etiqueta.
Nossas regras de proteção de ramificação funcionaram exatamente como planejado. Elas impediram que o código malicioso fosse mesclado à ramificação principal. Mas o invasor não precisava mesclar o código — ele só precisava de um commit no repositório (que qualquer branch de PR fornece) e a capacidade de mover uma tag. A proteção de branch nos deu uma falsa sensação de segurança abrangente.
As novas funcionalidades não protegem retroativamente.
O GitHub introduziu liberação imutabilidade Em outubro de 2025, foi lançada uma funcionalidade que impede a modificação de tags associadas a versões. Tínhamos isso em nosso radar, mas não havíamos compreendido completamente suas implicações:
- Isso protege apenas as tags associadas a versões do GitHub, não as tags independentes.
- Não oferece proteção retroativa — as versões existentes criadas antes da ativação do recurso permanecem mutáveis.
- As regras de proteção de tags (um recurso separado) devem ser configuradas independentemente.
Se tivéssemos habilitado a imutabilidade da versão e garantido que a tag v5 estivesse associada a uma versão protegida, o envenenamento da tag teria falhado.
Escopos de aplicativos GitHub excessivamente permissivos
O aplicativo GitHub tinha permissões de escrita que excediam suas necessidades operacionais. Em uma organização complexa com vários aplicativos, bots e integrações, é fácil que as permissões se acumulem além do necessário. Cada permissão adicional representa uma superfície de ataque adicional.
Correções ao Registro Público
O relatório dos pesquisadores foi fundamental para alertar a comunidade, e agradecemos a sua rápida resposta. No entanto, nossa investigação interna encontrou alguns detalhes que divergem do relato deles:
- Cronologia do envenenamento por etiquetasO relatório do pesquisador indica que a alteração da tag v5 ocorreu aproximadamente às 10h49 UTC do dia 3 de março, imediatamente após o fechamento dos PRs. Nossa investigação não conseguiu confirmar esse horário — eventos de push forçado de tags não são registrados no log de atividades do repositório do GitHub. O que sabemos é que a tag foi envenenada em algum momento após a ação maliciosa. commit foi criado e antes de a comunidade o descobrir em 9 de março.
- As commit não foi “assinado com o e-mail de um responsável pela manutenção”. O relatório do pesquisador descreve o primeiro ataque malicioso. commit como “assinado com o endereço de e-mail de um mantenedor”, mas isso confunde metadados do autor do Git com assinatura criptográfica — são coisas fundamentalmente diferentes. commit Não foi assinado criptograficamente. O atacante simplesmente definiu o campo de autor do Git para o e-mail de outro mantenedor — algo que qualquer um pode fazer, já que os metadados do autor do Git são autodeclarados e não autenticados. commit A atualização foi enviada usando o PAT (Personal Access Token) do mantenedor comprometido; o mantenedor cujo e-mail foi usado não foi comprometido e só aparece no registro de atividades do repositório a partir das 12:21 UTC como parte da equipe de resposta a incidentes.
- As identidades envolvidasO pesquisador descreveu a identidade do mantenedor e o bot do aplicativo GitHub como evidências de "credenciais roubadas, e não de ação interna". Podemos confirmar que o PAT clássico de um mantenedor e a chave privada do aplicativo GitHub foram comprometidos. Ambos foram usados pelo mesmo atacante externo. O PR #48 aparece sob o usuário fantasma porque foi criado pela instalação do aplicativo GitHub — e não por uma conta humana excluída.
- O número de repositórios afetadosO relatório do pesquisador mencionou mais de 137 repositórios usando @v5. Nossa análise dos resultados da busca de código no GitHub não confirmou esse número. No momento de nossa análise mais recente, não encontramos nenhum repositório público usando ativamente xygeni/xygeni-action@v5 em fluxos de trabalho executáveis. As referências identificadas correspondiam a exemplos de documentação em repositórios da Xygeni, que já foram atualizados. Na prática, a maioria dos clientes usa o download do scanner baseado em CLI e o recurso Managed Scan da Xygeni, que invoca internamente a ação e usa uma versão com SHA fixado e validada internamente, que não é afetada pela manipulação da tag. Como a Busca de Código do GitHub indexa apenas repositórios públicos, não podemos determinar com 100% de certeza se repositórios privados podem ter referenciado a tag. Com base nas informações disponíveis, a exposição real a jusante parece ser significativamente menor do que a relatada inicialmente.
[Esta seção será atualizada assim que nossa investigação for concluída.]
Ações de resposta
Resposta imediata (3 de março)
- Solicitações de pull maliciosas foram sinalizadas e bloqueadas (a proteção de branch impediu a mesclagem).
- O código malicioso foi extraído e preservado para análise forense.
- Domínio C2 e IP registrados como Indicadores de Comprometimento
- O aplicativo GitHub comprometido (xygeni-onboarding-app-dev) foi removido do repositório.
- Todos os PATs contribuintes foram rotacionados.
- Os registros de auditoria do repositório foram revisados — nenhuma evidência de fusões não autorizadas anteriores.
Orientação de Remediação
Remediação (9 a 10 de março)
- A tag v5 comprometida foi removida.
- Liberar imutabilidade Foi ativada para o repositório e aplicada globalmente em todos os repositórios pertencentes à Xygeni.
- As regras de proteção das agências foram reforçadas, incluindo a obrigatoriedade de assinatura de um representante. commits (Xygeni usa suporte de hardware commit assinatura)
- A tag v5 não foi recriada intencionalmente, para deixar claro que havia sido comprometida e para incentivar a migração para referências com SHA-pin.
- A documentação foi atualizada para incluir a versão completa. commit SHA (13c6ed2797df7d85749864e2cbcf09c893f43b23) correspondente à versão 6.4.0
- O GitHub Actions foi temporariamente desativado no repositório como medida de precaução.
- As permissões de escrita foram restritas — apenas dois mantenedores designados e dois administradores do repositório mantêm acesso de escrita.
Para usuários do xygeni-action
Se você estiver usando xygeni/xygeni-action@v5, você deve:
- Atualização imediata seu fluxo de trabalho para fixar no cofre commit SHA:
uses: xygeni/xygeni-action@13c6ed2797df7d85749864e2cbcf09c893f43b23
- Audite seus logs de CI para quaisquer conexões de saída para 91.214.78.178 ou security-verify.91.214.78.178.nip.io durante o período entre 3 e 9 de março de 2026.
- Gire quaisquer segredos que foram expostos a corredores CI durante esse período.
- Como alternativa, você pode usar um download e verificação direta do scanner
Por que não divulgamos publicamente em 3 de março
Esta é uma pergunta para a qual devemos uma resposta honesta.
Em 3 de março, quando nossa equipe respondeu aos PRs maliciosos, a avaliação foi de que o ataque havia sido totalmente contido na fase de PR. As regras de proteção de branch foram mantidas. Nenhum código malicioso foi mesclado ao branch principal. Nenhum executor de CI executou o payload. O PAT comprometido foi rotacionado, o aplicativo GitHub foi removido e os logs de auditoria do repositório não mostraram evidências de mesclagens não autorizadas anteriores. O incidente foi classificado como de gravidade média (P2) — uma tentativa de intrusão bloqueada.
Com base nessa avaliação, nenhuma divulgação pública foi considerada necessária. Em retrospectiva, essa avaliação estava incompleta.
O que não percebemos foi o envenenamento da tag. A tag v5 havia sido movida silenciosamente para apontar para o arquivo malicioso. commit, mas isso não era visível nas mesmas superfícies de auditoria que estávamos revisando. Os registros de atividade do repositório do GitHub mostram as alterações de tags de forma diferente das operações de branch, o que tornou a modificação menos visível durante a investigação inicial. Nossa resposta ao incidente se concentrou no vetor de ataque visível — o pull requests e a filial principal — e não verificaram se as etiquetas haviam sido adulteradas.
Em retrospectiva, esta é uma das principais lições deste incidente: não se pode divulgar o que desconhecemos. Nossa resposta em 3 de março foi rápida e eficaz contra a ameaça que conseguimos identificar. Mas o atacante tinha um segundo vetor, mais furtivo, que permaneceu indetectado por seis dias — até ser descoberto pela comunidade.
Divulgação Pública (9 de março)
Em 9 de março de 2026, membros da comunidade abriram uma discussão. #54Questionando o código malicioso e a tag v5 comprometida, os pesquisadores publicaram uma análise detalhada que ajudou a aumentar a conscientização em todo o ecossistema.
Gostaríamos de reconhecer o papel do pesquisador em ampliar o alerta e fornecer orientações práticas aos usuários afetados. Também gostaríamos de esclarecer alguns detalhes do relatório, nos quais nossa investigação interna chegou a conclusões diferentes — abordamos esses pontos na seção de Correções.
Lições para o Ecossistema
- Ações de fixação por SHA, não por tagTags mutáveis representam a maior superfície de ataque em todo o ecossistema do GitHub Actions. Use Ação@ em todos os fluxos de trabalho de produção.
- Compreenda os limites de cada recurso de segurança.A proteção de ramificações protege as ramificações. A proteção de tags protege as tags. A imutabilidade de versões protege as versões. Elas não são intercambiáveis, e as lacunas entre elas são exatamente onde os atacantes atuam.
- Audite as permissões do aplicativo GitHub implacavelmente.Cada aplicativo instalado com permissão de escrita é um vetor potencial de movimentação lateral. Aplique o princípio do menor privilégio, rotacione as chaves e revise periodicamente quais aplicativos estão instalados em repositórios críticos.
- Trate os executores de CI como ambientes hostis.O monitoramento de saída de rede, os executores efêmeros e o isolamento de segredos não são opcionais para repositórios na cadeia de suprimentos de software.
- Novos recursos de segurança exigem adoção proativa.A imutabilidade de versões do GitHub estava disponível meses antes deste incidente. Recursos que não estão habilitados não oferecem proteção — segurança não é um recurso padrão.
- Não assinado commits podem ter identidades forjadasGit commit autor e commitOs campos são autodeclarados — qualquer pessoa pode definir qualquer valor para eles. Sem criptografia commit assinatura (GPG, SSH ou S/MIME), não há garantia de que um commit Na verdade, o conteúdo foi criado pela pessoa que alega ser. Nesse incidente, o atacante identificou o autor do primeiro conteúdo malicioso. commit para o e-mail de um mantenedor diferente, criando uma atribuição falsa. Exigindo assinatura. commitO uso de regras de proteção de ramificação elimina esse vetor.
- A complexidade aumenta a superfície de ataque.A interação entre PATs, GitHub Apps, regras de proteção de branches, semântica de tags e imutabilidade de releases criou um cenário onde o atacante encontrou brechas que nenhuma dessas funcionalidades, individualmente, cobria. Simplifique sempre que possível. Compreenda o modelo de ameaça completo, mesmo quando não for possível compreendê-lo por completo.
Indicadores de Compromisso (IOCs)
| Formato | Valor |
|---|---|
| Endereço IP | 91.214.78.178 |
| Domínio C2 | security-verify.91.214.78.178.nip.io |
| Pontos finais C2 | /b/in (registro), /b/q (tarefa), /b/r (exfiltração) |
| Cabeçalho de autenticação | XB: sL5x#9kR!vQ2$mN7 |
| ASN | AS215826 (Partner Hosting LTD) |
| servidor | nginx/1.18.0 (Ubuntu) |
| TLS | Certificado autoassinado |
Agradecimentos
Agradecemos aos pesquisadores de segurança e membros da comunidade que relataram este problema, incluindo os colaboradores da issue. #54 e aos pesquisadores por suas análises públicas. Transparência e colaboração são a forma de tornar a cadeia de suprimentos de software mais resiliente para todos.





