Um invasor tentou explorar uma vulnerabilidade crítica do GitLab no próprio servidor do projeto Alpine Linux uma semana depois de o GitLab lançar uma correção, informou a Alpine Linux em 28 de outubro.
A falha, CVE-2026-97229 (sigla de Common Vulnerabilities and Exposures, ou Vulnerabilidades e Exposições Comuns, sistema de identificação de falhas de segurança), tem pontuação CVSS de 10,0 (sigla de Common Vulnerability Scoring System, escala que mede a gravidade de vulnerabilidades). Ela pode permitir que um invasor execute código em um servidor GitLab por meio de uma expressão regular elaborada em uma configuração de CI (integração contínua). A Alpine não encontrou evidências de que o ataque tenha funcionado, mas não consegue descartar essa possibilidade. Por isso, reconstruiu o servidor do zero e redefiniu a senha de todas as contas.
A correção do GitLab consiste em um conjunto de patches, ou correções pontuais, aplicados ao Ruby que o GitLab distribui em seus próprios pacotes e imagens de contêiner. A imagem do GitLab usada pela Alpine, no entanto, utilizava o Ruby padrão, então a atualização do servidor para a versão 19.3.6, em 22 de outubro, não corrigiu a falha.
Para quem executa o GitLab com um Ruby próprio, compilado a partir do código-fonte ou em uma imagem de contêiner própria, “atualizar o GitLab não é suficiente”, afirmou a Alpine. Esses servidores também precisam do Ruby 3.3.13, 3.4.12, 4.0.9 ou versão posterior, e os usuários da imagem alpinelinux/gitlab precisam baixar novamente a versão 19.3.6.
O servidor gitlab.alpinelinux.org hospeda o aports, repositório a partir do qual são compilados os pacotes da Alpine. Segundo a empresa, os pacotes gerados entre 20 e 24 de outubro, assim como as versões de 21 de outubro, vieram de alterações no aports verificadas em registros externos ao GitLab.
Essas versões incluem os arquivos minirootfs, a partir dos quais são construídas as imagens Docker oficiais da Alpine. A empresa está estendendo as verificações até 27 de outubro, data em que fechou o servidor. As chaves que assinam seus pacotes e versões nunca estiveram no servidor GitLab.
Como o ataque se desenrolou
Em 13 de outubro, a Alpine atualizou o servidor para o GitLab 19.3.4 em vez do 19.3.5, o que a empresa chama de erro. O servidor ainda estava nessa versão, sem a correção de 12 de outubro, quando uma conta recém-registrada começou a sondar o sistema em 20 de outubro.
A conta enviou configurações de CI elaboradas ao servidor nos dias 20 e 21 de outubro. Elas derrubaram processos de trabalho (workers) do GitLab em 8 ocasiões, e o ataque principal, em 21 de outubro, também provocou erros 502 e fez com que tarefas de CI falhassem.
Em 4 dessas quedas, o invasor avançou parte da exploração e falhou na etapa seguinte, segundo a Alpine. O invasor também baixou a imagem de contêiner do GitLab da Alpine, o que, nas palavras da empresa, “sugere que estavam ajustando a exploração exatamente à nossa versão”.
A Alpine bloqueou a conta em 23 de outubro. O invasor voltou nos dias 25 e 26 de outubro e tentou recuperar o acesso, mas essas tentativas falharam, afirmou a empresa.
Em 26 de outubro, a Alpine constatou que o servidor ainda estava vulnerável mesmo após a atualização para a versão 19.3.6, feita em 22 de outubro. No dia seguinte, fechou o GitLab para todos, exceto seus desenvolvedores e servidores de build, e começou a reconstruí-lo.
A reconstrução terminou em 28 de outubro. A Alpine também substituiu as chaves secretas do GitLab, e o servidor reconstruído usa o Ruby 3.3.13 ou posterior, que contém a correção. A empresa está testando o sistema antes de reabri-lo ao público.
O que a Alpine pode e não pode descartar
A Alpine não encontrou nenhum sinal de que o código do invasor tenha sido executado no servidor. Os testes de tempo não mostraram atrasos; não havia arquivos, chaves, hooks (gatilhos automáticos) ou processos inesperados; e nenhum dado privado foi enviado de volta ao invasor por meio de qualquer requisição web ou de API visível para a empresa.
Ainda assim, a Alpine não pode ter certeza. “Uma exploração bem-sucedida não deixaria nenhuma falha nem nenhum rastro nos logs web”, afirmou a empresa. Alguns registros do dia do ataque se perderam, incluindo os logs de tarefas em segundo plano e o sistema de arquivos do contêiner antigo, e nem a Alpine nem seu provedor de hospedagem registraram as conexões de rede de saída.
Como as evidências necessárias para confirmar a execução de código não existem mais, a Alpine tratou o servidor como comprometido e o reconstruiu para remover qualquer ponto de apoio que uma exploração bem-sucedida pudesse ter deixado.
Se o ataque tivesse sucesso, poderiam ter sido expostos:
- Endereços de e-mail, nomes e endereços IP de todos os usuários
- Hashes de senhas
- Segredos de 2FA (autenticação de dois fatores), variáveis de CI/CD (integração e entrega contínuas) e tokens de runners (executores de CI/CD)
- Credenciais de webhooks, integrações e espelhos de push
- Tokens de acesso pessoal, que são armazenados como hashes
- Repositórios privados, além de problemas (issues) e solicitações de merge (merge requests) confidenciais
Além da redefinição de senhas e da troca das chaves secretas, a Alpine não informou se os tokens de runners, as variáveis de CI/CD, os tokens de acesso ou as credenciais de integração armazenados no servidor foram substituídos.
Para verificar seus pacotes, a Alpine confirmou que todas as alterações no aports adicionadas entre 20 e 22 de outubro chegaram por meio de um push registrado feito por um desenvolvedor conhecido. A checagem foi feita em registros que, segundo a empresa, o invasor não conseguiria acessar: uma cópia do repositório mantida por um desenvolvedor e todos os 45 servidores de build. Todos os pacotes gerados entre 20 e 24 de outubro vieram de alterações no aports conforme publicadas em git.alpinelinux.org.
Por que a atualização do GitLab não corrigiu o problema
O GitLab compila as expressões regulares das configurações de CI com o Ruby, e o bug por trás do CVE-2026-97229 está no Onigmo, o mecanismo de expressões regulares embutido no Ruby.
A correção de 12 de outubro do GitLab resolveu o problema ao aplicar patches no Ruby dentro dos pacotes Linux e nas imagens de contêiner da empresa. As versões corrigidas do próprio Ruby foram lançadas em 22 e 23 de outubro.
Atualizar o GitLab não altera o Ruby do servidor. Assim, uma instalação do GitLab sobre o Ruby padrão mantém a falha até que o próprio Ruby seja atualizado para uma versão corrigida, como constatou a Alpine.
Os pacotes Linux corrigidos do GitLab e suas imagens oficiais de contêiner trazem o Ruby corrigido. Uma instalação compilada por conta própria, ou uma imagem de contêiner que instala o Ruby separadamente, como fez a Alpine, não recebe a correção.
Até 29 de outubro, nenhum dos comunicados de correção do GitLab, de 12 e 21 de outubro, orienta os administradores de instalações compiladas a atualizar o Ruby. O guia de instalação compilada do GitLab ainda indica o Ruby 3.2 como versão mínima, e o Ruby 3.2 chegou ao fim de vida em abril e não receberá correções.
Quais servidores GitLab estão expostos
O aviso do GitLab diz que, “em determinadas condições”, a falha poderia permitir que um usuário não autenticado executasse código no servidor. O GitLab.com e o GitLab Dedicated já estão corrigidos.
A Rapid7 desenvolveu uma exploração funcional em laboratório e publicou um código de prova de conceito em 13 de outubro. A exploração executou comandos como o usuário git do GitLab em uma imagem oficial 19.4.1 sem correção, mas a mesma entrada não foi executada na imagem 19.4.2, já corrigida.
Essa exploração exige, antes de tudo, acesso de escrita: o invasor precisa enviar um arquivo .gitlab-ci.yml malicioso e um caminho de arquivo com caracteres UTF-8 (padrão de codificação de caracteres) para uma branch de um projeto público. Esse requisito não se aplica a servidores em que novos usuários podem se registrar e criar projetos.
Na rota testada pela Rapid7, “apenas a requisição final de validação de CI (CI lint) não é autenticada”. As próprias notas de detecção do GitLab também afirmam que o invasor precisa primeiro criar esse caminho de arquivo por meio de APIs comuns de repositório. A Rapid7 ainda não sabe como o ataque descrito no relatório original enviado ao GitLab, que continua privado, contorna a etapa de escrita.
A Alpine não informou como as configurações de CI de seu invasor chegaram ao GitLab, nem se novas contas podiam criar projetos públicos em seu servidor.
O CVE-2026-97229 não constava no catálogo de vulnerabilidades exploradas conhecidas da CISA (Agência de Segurança Cibernética e de Infraestrutura dos EUA) na atualização de 28 de outubro.
O que os administradores do GitLab devem fazer
As versões de 21 de outubro do GitLab são as mais recentes de cada branch listada abaixo e também corrigem o CVE-2026-110264, outra falha separada em expressões regulares.
A versão que corrige um servidor depende de como o GitLab foi instalado:
- Pacote Linux do GitLab ou imagens oficiais de contêiner: atualize para a versão mais recente da sua branch.
- Instalações compiladas por conta própria, ou imagens que instalam seu próprio Ruby: atualize o GitLab e o Ruby para a versão 3.3.13, 3.4.12, 4.0.9 ou posterior. O Ruby 3.2 não receberá a correção, portanto servidores com essa versão precisam migrar para uma das versões citadas.
O aviso do GitLab indicava a versão 19.3.4 como corrigida para a branch 19.3 quando foi publicado, em 12 de outubro. Agora cita a 19.3.5 e lista a 19.3.4 como afetada, então servidores que ainda estão na 19.3.4 devem migrar para a 19.3.6.
Se um servidor não puder ser atualizado imediatamente, a Rapid7 sugere restringir o acesso anônimo a projetos públicos, impedir que usuários não confiáveis criem ou escrevam em projetos públicos ou bloquear a rota de validação de CI. Essas medidas cobrem apenas a rota de exploração da Rapid7 e não corrigem o compilador de expressões regulares vulnerável, afirmou a empresa.
O GitLab publicou seis regras de detecção para tentativas de exploração contra servidores autogerenciados, escritas no formato Sigma (padrão aberto para regras de detecção de ameaças). Quatro delas, que o GitLab marca como experimentais, procuram padrões hostis em avisos de expressões regulares de CI e em requisições GraphQL ciLint, caminhos de arquivo incomumente longos com caracteres não ASCII (fora da tabela ASCII básica) e relatórios de falha do Ruby que apontam para o Onigmo.
A orientação que acompanha essas regras alerta que uma exploração bem-sucedida pode não deixar nenhuma falha e indica as seguintes medidas adicionais:
- Procurar arquivos pertencentes ao usuário git em /tmp, processos filhos inesperados do Puma ou do Sidekiq, conexões de saída e alterações em crontabs ou chaves SSH do usuário git.
- Se houver sinais de execução de código, tratar o servidor como comprometido e rotacionar os segredos do arquivo gitlab-secrets.json, todas as variáveis de CI/CD, todos os tokens de runners e todos os tokens de acesso.
- Limitar quem pode criar contas e tokens de acesso pessoal no servidor.
O que os usuários da Alpine devem fazer
Os titulares de contas precisarão definir uma nova senha pelo link “Esqueceu sua senha?”, na página de login, quando o gitlab.alpinelinux.org for reaberto, afirmou a Alpine. A empresa também identificou tentativas automatizadas de login em seu GitLab usando senhas vazadas de outros sites. Quem usou a senha do gitlab.alpinelinux.org em outros serviços deve alterá-la neles.
Os usuários da imagem alpinelinux/gitlab devem baixar novamente a alpinelinux/gitlab:19.3.6. A imagem publicada em 27 de outubro contém o Ruby 3.3.13, enquanto qualquer imagem 19.3.6 baixada antes disso, e todas as tags anteriores, estão vulneráveis.
Os pacotes Ruby da própria Alpine já têm a correção: Ruby 3.4.12 nas versões Alpine 3.22, 3.23, 3.24 e edge, e Ruby 3.3.13 na Alpine 3.21. Basta executar apk upgrade para instalá-la.
Os mantenedores do Ruby afirmam que o bug só importa para programas que compilam uma expressão regular a partir de um texto controlado por um invasor, e que a configuração Regexp.timeout do Ruby não oferece proteção contra ele.