- Apenas uma falha no protocolo interno do caminho de
git pushjá permitia execução remota de código no backend, e o GitHub.com já foi mitigado, mas o GHES ainda precisa receber o patch - Como a push option, uma entrada controlada pelo usuário, era inserida diretamente no cabeçalho
X-Stat, bastava um ponto e vírgula para injetar um novo campo, explorando o comportamento de last-write-wins, em que o valor posterior da mesma chave sobrescreve o anterior - Entre os campos que podiam ser injetados, a combinação de
rails_env,custom_hooks_direrepo_pre_receive_hookspermitia contornar o sandbox e executar hooks em um caminho definido pelo atacante com privilégios do usuáriogit - Pelo mesmo mecanismo, até a flag de enterprise mode do GitHub.com podia ser injetada, o que confirmou execução de código em um shared storage node e levou a uma situação em que também era possível ler repositórios de outros usuários e organizações presentes no nó
- Em uma arquitetura multisserviço onde serviços diferentes confiam em um formato compartilhado, a combinação de falta de sanitização de entrada, caminhos de execução não produtivos e ausência de validação de caminho pode se transformar em uma vulnerabilidade grave
Resposta imediata e escopo do impacto
- No GitHub.com, esse problema já foi mitigado e não exige ação adicional
- O GitHub Enterprise Server exige resposta imediata, com upgrade para GHES 3.19.3 ou superior, que inclui a correção para
CVE-2026-3854 - O intervalo de versões vulneráveis é GHES 3.19.1 ou inferior; as versões corrigidas informadas são
3.14.24,3.15.19,3.16.15,3.17.12,3.18.6e3.19.3 - No momento da redação, 88% das instâncias GHES ainda estavam vulneráveis
- Informações técnicas adicionais e procedimentos de recuperação do GitHub podem ser consultados no blog de segurança do GitHub
- Clientes da Wiz podem identificar instâncias GHES vulneráveis com a consulta pré-configurada do Wiz Threat Center
Contexto da investigação e abordagem
- A infraestrutura interna de git do GitHub é o caminho que processa todo
git push, e vários serviços internos são escritos em linguagens de programação diferentes - Nessa estrutura multisserviço, diferenças na forma como cada componente interpreta e confia em dados compartilhados podem resultar em vulnerabilidades
- Antes, extrair e auditar a grande quantidade de binários compilados de caixa-preta que compõem esse pipeline exigia tempo excessivo e muito trabalho manual
- Com ferramentas reforçadas por IA e engenharia reversa automatizada baseada em
IDA MCP, foi possível analisar rapidamente os binários compilados e reconstruir os protocolos internos - Nesse processo, foi feito um rastreamento sistemático dos pontos em que a entrada do usuário influenciava o comportamento do servidor ao longo de todo o pipeline, revelando uma falha fundamental no fluxo de entrada
Arquitetura interna e fronteiras de confiança
- Quando um
git pushchega via SSH, a requisição passa porbabeld,gitauth,gitrpcde, em seguida, pelo pre-receive hook - O
babeldé o ponto de entrada de todas as operações git, recebe a conexão SSH e encaminha a autenticação paragitauth - O
gitauthverifica as credenciais do usuário e as permissões de push no repositório, além de retornar políticas de segurança como limite de tamanho de arquivo e regras de nome de branch - Com base nessa resposta, o
babeldmonta um cabeçalho internoX-Statcontendo metadados de segurança - O
gitrpcdrecebe o cabeçalhoX-State configura o ambiente dos processos subsequentes, confiando totalmente nobabeldsem autenticação própria - O pre-receive hook verifica limite de tamanho de arquivo, regras de nome de branch, integridade de LFS e hooks customizados definidos pelo administrador antes de aceitar o push
- O elo central era o cabeçalho X-Stat, que armazena pares
key=valueseparados por; - Os serviços internos dividem
X-Statcom base em;e preenchem um mapa; quando a mesma chave aparece duas vezes, o valor posterior sobrescreve o anterior segundo a regra de last-write-wins - O
babeldtambém inclui noX-Statas push options passadas comgit push -o, em campos comopush_option_0,push_option_1epush_option_count
Causa da vulnerabilidade: injeção de campos em X-Stat
- O
babeldcopiava o valor da push option, uma entrada controlada pelo usuário, para o cabeçalhoX-Statsem sanitizar ponto e vírgula - Como
;é o separador de campos doX-Stat, um único ponto e vírgula dentro da push option permitia escapar do campo original e criar um novo campo controlado pelo atacante - Por exemplo, ao injetar
large_blob_rejection_enabled=bool:falsedentro depush_option_0, o valorbool:truedefinido antes acabava sendo sobrescrito pelo valor posterior - Esse comportamento foi confirmado tanto na análise dos binários quanto em capturas de pacote de uma instância GHES real
- A combinação de engenharia reversa com análise em nível de wire permitiu mapear os campos
X-Statque podiam ser injetados - Em especial, foram identificados como sensíveis os campos
rails_env,custom_hooks_dir,repo_pre_receive_hooks,large_blob_rejection_enabled,reject_sha_like_refseuser_operator_mode - Entre eles,
rails_env,custom_hooks_direrepo_pre_receive_hooksformavam o caminho principal até a execução remota de código
O caminho até RCE no GHES
- O GHES suporta custom pre-receive hooks executados antes da aceitação do push
- O binário de pre-receive tinha dois caminhos de execução diferenciados apenas pelo valor de
rails_envemX-Stat - Se o valor fosse
production, o hook era executado dentro do sandbox; para qualquer outro valor, ele era executado diretamente com privilégios do usuário de serviçogit, sem sandbox nem isolamento - Assim, ao injetar um valor não produtivo em
rails_env, era possível contornar o sandbox - Em seguida, ao injetar
custom_hooks_dir, o atacante passava a controlar o diretório-base usado para localizar scripts de hook - Por fim, ao injetar em
repo_pre_receive_hooksuma definição de hook com path traversal, a resolução de caminho no binário combinava o diretório controlado pelo atacante com a carga de traversal, apontando para um caminho arbitrário no sistema de arquivos - O caminho de execução não produtivo então executava diretamente esse caminho resolvido, sem argumentos, sem sandbox e como usuário de serviço
git - Na validação prática, uma única execução de
git pushretornou a saídauid=500(git), confirmando RCE com privilégios do usuáriogit - Com esse nível de acesso, era possível obter controle total da instância GHES, incluindo leitura e escrita no sistema de arquivos e visibilidade sobre configurações de serviços internos
Expansão para o GitHub.com e exposição cross-tenant
- Ao aplicar a mesma cadeia de exploração a um repositório no GitHub.com, inicialmente o push foi bem-sucedido, mas os custom hooks não eram executados
- Ao injetar
user_operator_mode=bool:truee comparar a saída de debug nas duas plataformas, ficou claro que o GitHub.com não alcançava o caminho de código de custom hooks - Engenharia reversa adicional confirmou a existência, no cabeçalho
X-Stat, de uma flag booleana que controla o comportamento de enterprise mode do servidor - No GHES, essa flag é
truepor padrão, então o caminho de custom hooks fica sempre ativado; no GitHub.com, o padrão éfalse, então esse caminho não é alcançado em condições normais - Como essa flag também podia ser injetada pelo mesmo mecanismo, bastou injetar mais um campo para fazer toda a cadeia de exploração funcionar também no GitHub.com
- Em seguida, a saída do comando
hostnamefoi retornada de dentro da infraestrutura do GitHub.com, confirmando RCE no GitHub.com - O GitHub.com é uma plataforma multitenant, em que repositórios de vários usuários e organizações ficam armazenados em infraestrutura de backend compartilhada
- A execução de código ocorreu em um shared storage node, onde o usuário
gittinha amplos privilégios no sistema de arquivos para processar todas as operações de repositório daquele nó - Se esse usuário for comprometido, repositórios de outras organizações e usuários presentes no nó também podem ser lidos, independentemente de seus proprietários
- Ao enumerar as entradas de índice de repositórios acessíveis em dois nós comprometidos, foram encontrados milhões de entradas em cada nó, incluindo repositórios de outros usuários e organizações
- O conteúdo real de repositórios de outros tenants não foi acessado; foi usado apenas uma conta de teste própria para verificar que os privilégios de sistema de arquivos do usuário
gitpermitiam leitura de todos os repositórios no nó
Principais lições e cronograma de divulgação
- Bastava um único
git pushpara explorar a falha no protocolo interno e obter execução remota de código na infraestrutura de backend - Quando vários serviços escritos em linguagens diferentes trocam dados por meio de um protocolo interno compartilhado, as próprias suposições de confiança de cada serviço se tornam superfície de ataque
- Nesta cadeia, um serviço inseria o valor de push option sem filtragem, outro confiava em todos os campos de
X-Stat, e o pre-receive hook assumia querails_envseriaproductionem ambiente operacional - Caminhos de código não produtivos em binários de produção, ausência de validação de path traversal em scripts de hook e falta de sanitização de entrada em protocolos baseados em delimitadores são padrões que podem aparecer em outras bases de código
- Equipes que operam arquiteturas multisserviço precisam verificar especialmente como entradas controladas pelo usuário fluem por protocolos internos quando configurações sensíveis de segurança derivam de formatos de dados compartilhados
- Nesta pesquisa, ferramentas de engenharia reversa reforçada por IA, incluindo
IDA MCP, permitiram acelerar a análise de binários compilados e a reconstrução de protocolos internos - À medida que essas ferramentas amadurecem, elas tendem a desempenhar um papel ainda mais importante na descoberta de classes de vulnerabilidades que exigem análise profunda entre componentes
- No cronograma de divulgação, em
2026-03-04foi descoberta a vulnerabilidade de injeção de push option em X-Stat; no mesmo dia, foi confirmada a RCE noGHES 3.19.1, o problema foi reportado ao GitHub e a correção do GitHub.com também foi implantada naquele dia - Em
2026-03-10, foram atribuídos a CVE-2026-3854 e oCVSS 8.7, e o patch do GHES foi publicado - Em
2026-04-28, houve a divulgação pública
1 comentários
Comentários do Hacker News
Basicamente deixaram uma string arbitrária enviada pelo usuário final via
git push -oentrar junto nos cabeçalhos de segurança críticos definidos pelo serviço de autenticação internoé fácil falar depois que aconteceu, mas mesmo assim isso é absurdo demais
A abordagem de engenharia reversa com reforço de IA mostra bem os pontos fortes dos agentes LLM atuais
como são modelos muito treinados em código, eles podem acelerar enormemente a compreensão do interior de sistemas complexos
pesquisa em segurança normalmente mistura 1) entender comportamentos internos complexos e 2) encontrar vulnerabilidades ali dentro,
e muitas vezes, quando o mecanismo interno real fica claro, a vulnerabilidade em si aparece de forma surpreendentemente fácil
CVE-2026-3854 não era exatamente um caso óbvio mesmo conhecendo o interior,
mas se estivesse exposta numa superfície de ataque mais tradicional ou acessível, acho que essa injeção de comando teria sido descoberta rapidamente
mas ultimamente parece que essa tendência ficou meio confusa, ou até deliberadamente atrapalhada por quem quer preservar o lock-in de dev/vendor criado pela complexidade sintática do C++
Parece mesmo que tem gente da Wiz trabalhando nisso, porque o resultado ficou bem bom
o produto ainda se sustenta muito bem apesar do crescimento extremo e do inchaço de funcionalidades,
e a equipe de segurança vive encontrando coisas realmente interessantes
osv-scanneretrivypara olhar apenas os casos críticosenquanto fica quieto para atividades meio suspeitas, tipo consultar DC via CLI e resetar credenciais, o que é frustrante
Quando o
babeldencaminha uma solicitação de push, ele coloca as push options no cabeçalho X-Stat da requisição interna,e esse valor é uma string arbitrária fornecida pelo usuário via
git push -omas como copiaram o valor sem sanitizar ponto e vírgula,
e
;é o separador de campos do X-Stat, isso permite escapar do campo original e criar novos campos controlados pelo atacanteé realmente o tipo de erro mais básico possível, a fruta estava tão baixa que parecia enterrada no chão
Mesmo sendo uma vulnerabilidade descoberta antes de qualquer exploração real,
fico me perguntando se precisava inflar o medo com expressões como BREAKING, unauthorized access e millions of repositories
https://x.com/wiz_io/status/2049153209982140718
o GitHub só teve sorte de esbarrar no fuzzing da Wiz, e não num ator estatal
O fato de que 88% das instâncias do GHES ainda não aplicaram um patch crítico de segurança lançado há 7 semanas parece bem sério
https://docs.github.com/en/enterprise-server@3.19/admin/release-notes#3.19.3
até aplicar um release de patch level exige algumas horas de downtime,
e nem existe um método de upgrade HA suportado, então mesmo clientes diligentes têm dificuldade para acompanhar a versão mais recente
quando reclamam, todo mundo manda migrar para o GitHub Enterprise Cloud,
mas também é questionável quantos topariam isso com facilidade hoje em dia
ainda assim, o GHES pelo menos não para durante as falhas diárias do github.com
e provavelmente estão esperando uma data com menor impacto operacional para fazer o upgrade
mas, se for uma instância pública, é preciso atualizar imediatamente
com as informações do artigo e o código-fonte público do GitHub Enterprise, não parece difícil montar uma reprodução
ou então dá para seguir o cronograma normal e torcer para nada acontecer; normalmente escolhem a segunda opção
não seria nada estranho um produto on-prem ser atualizado só uma vez por ano
em software enterprise com muito dado, era comum a instalação quebrar por qualquer detalhe e a equipe de operações precisar fazer rollback
upgrades antigos de SharePoint pareciam quase um lançamento de dados
Esse também é um grande feito da Wiz,
e parece um ponto de virada para mostrar o quanto ferramentas de IA impulsionam RE e descoberta de caminhos de comprometimento
é mais um dado mostrando que segurança não deve depender de security through obscurity
Todo mundo fala em substituir o GitHub, mas aí fica a pergunta: usar o quê?
se até um lugar do porte do GitHub acabou tendo RCE, é difícil garantir com tanta confiança que as alternativas serão melhores
https://news.ycombinator.com/item?id=46961345
https://news.ycombinator.com/item?id=47712656
e usar o GitHub só como espelho enquanto se aproveita o CI gratuito
segredos podem ficar com um provedor separado de hospedagem de secrets
ainda acho difícil acreditar como o Forgejo está responsivo e como o GitHub ficou lento
os internos ficam numa instância privada de Forgejo, e os públicos vão para o GitHub com espelhamento para o Forgejo
fiquei surpreso como o Forgejo é basicamente um binário único e fácil de configurar,
e como todos os serviços internos já apontam para o Forgejo, sair do GitHub causaria pouco atrito
com a imagem Docker all-in-one e alguns GitLab runners já dá conta de times pequenos a médios,
e não há motivo para complicar com a versão em Kubernetes a menos que isso seja realmente necessário
Já era impressionante ver a IA encontrar vulnerabilidades no código-fonte,
mas fazer isso até em executáveis binários é realmente surpreendente
o potencial é enorme, para o bem e para o mal
e mais uma vez aparece a lição de que dados não devem ser tratados como comandos
toda entrada de usuário precisa ser sanitizada
então ele ser forte em source-to-source ou text-to-source já era algo familiar,
e talvez não seja tão surpreendente que também funcione bem para entender versões em asm
ainda assim, continua sendo impressionante
Fico curioso se daria para determinar se isso foi realmente explorado
os logs de HTTP/git talvez permitam verificar até certo ponto se houve exploração,
mas é bem possível que não registrem exatamente o que foi acessado nem por quem
se o exploit podia rodar de forma independente no servidor git, por definição ele talvez conseguisse escapar do logging