CVE-2026-55200: corrija o libssh2 antes que seja tarde

Você rodou um git pull rotineiro hoje de manhã. Um repositório que parecia confiável, um servidor que você já tinha usado antes. Não digitou senha nenhuma, não respondeu a nenhum prompt. E mesmo assim, em teoria, código de um estranho pode ter rodado na sua máquina antes de qualquer autenticação acontecer. A culpa não é sua: é de uma biblioteca minúscula que você provavelmente nem sabia que estava ali, embutida no Git, no curl e no PHP.

Essa biblioteca é o libssh2, e a falha tem nome: CVE-2026-55200, nota CVSS 9.2, com prova de conceito pública desde o dia 27 de junho. Neste artigo você vai entender o que de fato acontece por baixo do handshake SSH, como descobrir em menos de um minuto se a sua máquina e a sua pipeline estão expostas, e o que fazer ainda hoje para fechar essa porta.

O que é o libssh2 e por que ele está em todo lugar

O libssh2 é uma biblioteca C que implementa o lado cliente do protocolo SSH2. Ela não é um programa que você instala de propósito. Ela vem de carona dentro de ferramentas que você usa o dia inteiro sem pensar duas vezes:

  • O curl usa libssh2 para falar scp:// e sftp://.
  • O Git, em muitas distribuições, usa libssh2 (via libgit2) para clonar e dar pull por SSH.
  • O PHP expõe a extensão ext-ssh2, que é um wrapper direto da lib.
  • Agentes de backup, ferramentas de deploy e automações de infraestrutura que copiam arquivos por SSH.

Quando eu trabalhei como Tech Leader em uma equipe de plataforma, levei um susto parecido: uma auditoria de segurança apontou uma CVE numa lib que ninguém da equipe lembrava de ter colocado no projeto. Ela tinha entrado como dependência transitiva de outra dependência, três níveis abaixo. É exatamente esse o ponto cego que a CVE-2026-55200 explora. Você não declara o libssh2, mas ele está lá.

Contexto técnico: o que a CVE-2026-55200 realmente faz

A falha está no parsing do handshake SSH, a fase em que cliente e servidor negociam algoritmos e trocam chaves, antes de qualquer autenticação. Esse detalhe é o que torna a falha tão grave: ela acontece pré-autenticação, ou seja, o atacante não precisa de senha nem de chave válida.

Segundo o relato técnico publicado pela CyberSecurityNews, o problema é um integer overflow na leitura do tamanho do pacote dentro da função de transporte. De forma simplificada, o código lê um campo de tamanho controlado pelo servidor e usa esse valor para alocar e copiar memória. Se o valor for manipulado para estourar o limite do tipo inteiro, a conta de alocação dá errado e o memcpy grava fora da região reservada.

/* Versao ILUSTRATIVA e simplificada do padrao da falha.
   NAO e o exploit real, e apenas para entender o conceito. */
int ssh2_transport_read(struct transport *t) {
    uint32_t packet_length = read_uint32(t->buffer); // valor vem do SERVIDOR
    uint32_t total = packet_length + padding + MAC_LEN; // pode estourar 32 bits

    // Se 'total' der a volta no inteiro, 'malloc' aloca POUCO...
    char *buf = malloc(total);
    // ...mas o memcpy copia MUITO, gravando fora do buffer.
    memcpy(buf, t->buffer, packet_length);
    return OK;
}

O resultado é uma escrita fora dos limites (heap overflow) acionada por um servidor SSH malicioso. Em um cenário realista, isso significa que se você se conectar a um host comprometido, ou a um mirror de repositório que finge ser legítimo, é a sua máquina cliente que sofre a execução de código, não o servidor. Esse ponto inverte a intuição de quem está acostumado a pensar em SSH só como problema de servidor.

Quem está afetado: todas as versões do libssh2 até a 1.11.1. A correção entrou no repositório oficial (commit de hardening da função de leitura), mas até a publicação deste artigo muitas distribuições ainda não tinham empacotado o patch. A janela de risco está aberta, e a prova de conceito já circula.

Como saber, hoje, se você está afetado

Nada de pânico. Antes de corrigir, você precisa saber onde o libssh2 vive na sua máquina. Bora auditar do jeito certo, começando pelo sistema operacional. Rode o comando da sua distribuição:

# Debian / Ubuntu
dpkg -l 'libssh2*' 2>/dev/null | grep libssh2

# RHEL / Fedora / Rocky / Alma
rpm -q libssh2

# macOS (Homebrew)
brew list --versions libssh2

# Alpine (muito comum em imagem Docker)
apk info -v | grep libssh2

Se a versão que aparecer for 1.11.1 ou anterior, essa máquina está na faixa vulnerável. Mas o pacote do sistema é só metade da história. O que importa de verdade é quais binários carregam a lib em tempo de execução. Confira as ferramentas de maior risco:

# O seu curl usa libssh2? Procure pela linha 'libssh2' na saida.
curl --version | grep -o 'libssh2/[0-9.]*'

# Quais bibliotecas dinamicas o curl carrega de fato?
ldd $(which curl) | grep ssh2

# O Git tem suporte a SSH via libssh2?
ldd $(which git) | grep ssh2

# PHP com a extensao ssh2 ativa?
php -m | grep -i ssh2

O detalhe que muita gente esquece: conferir os containers. A imagem base que você herdou no Dockerfile pode carregar uma versão antiga mesmo que o seu laptop esteja em dia. Rode a auditoria dentro da imagem, não só na máquina host:

# Audita a imagem que a sua pipeline usa, sem subir a aplicacao
docker run --rm minha-imagem:latest sh -c \
  '(dpkg -l "libssh2*" 2>/dev/null || apk info -v 2>/dev/null) | grep -i ssh2'

A correção: do patch rápido ao controle de supply chain

Com o diagnóstico em mãos, a remediação tem três camadas, da mais imediata para a mais estrutural.

1. Atualize o pacote do sistema. Essa é a correção real, não um remendo:

# Debian / Ubuntu
sudo apt-get update && sudo apt-get install --only-upgrade libssh2-1

# RHEL / Fedora
sudo dnf upgrade libssh2

# Alpine
apk upgrade libssh2

# Confirme a versao DEPOIS do upgrade (precisa ser > 1.11.1)
curl --version | grep -o 'libssh2/[0-9.]*'

2. Trave a versão na sua imagem. Não adianta corrigir o laptop e deixar o Dockerfile reintroduzir a versão vulnerável no próximo build. Force o upgrade na construção da imagem:

# Trecho de Dockerfile: garante libssh2 corrigido na imagem
RUN apt-get update && \
    apt-get install -y --only-upgrade libssh2-1 && \
    rm -rf /var/lib/apt/lists/*

3. Automatize a verificação na pipeline. O jeito que os times sêniores fazem não é caçar CVE na mão toda terça-feira. É deixar a esteira falhar sozinha quando uma dependência vulnerável aparece. Um pequeno script de auditoria, defensivo, que apenas a versão instalada e devolve código de erro, já resolve:

#!/usr/bin/env python3
# audita_libssh2.py - so LE a versao e falha se for vulneravel.
# Nao explora nada. Use no CI como gate de seguranca.
import subprocess, re, sys

VERSAO_SEGURA = (1, 11, 2)  # primeira versao corrigida

def versao_do_curl():
    saida = subprocess.run(["curl", "--version"],
                           capture_output=True, text=True).stdout
    m = re.search(r"libssh2/(\d+)\.(\d+)\.(\d+)", saida)
    return tuple(int(x) for x in m.groups()) if m else None

v = versao_do_curl()
if v and v < VERSAO_SEGURA:
    print(f"VULNERAVEL: libssh2 {v} < 1.11.2 (CVE-2026-55200)")
    sys.exit(1)  # quebra o build de proposito
print("OK: libssh2 corrigido ou ausente")

Repare na diferença entre o jeito errado e o jeito certo aqui. O jeito errado é tratar isso como um chamado pontual: alguém atualiza um servidor, fecha o ticket e segue a vida. O jeito certo é transformar a verificação em um portão automático que vive na pipeline e impede que a versão vulnerável volte sem ninguém perceber.

Como mitigação de rede enquanto o patch não chega em todos os lugares: evite que automações se conectem por SSH a hosts fora da sua lista de confiança, e prefira https:// em vez de git+ssh para clonar de mirrors externos. Isso reduz a superfície sem depender de cada máquina estar atualizada.

O que muda na prática (e onde o risco é maior)

Para a maioria das pessoas, o impacto direto está em três frentes, e vale priorizar nessa ordem:

  • Runners de CI/CD. São máquinas que clonam, baixam artefatos e copiam arquivos por SSH o tempo todo, muitas vezes de origens que você não controla. Um runner comprometido é a pior das hipóteses, porque ele tem credenciais de deploy.
  • Laptops de desenvolvedor. Todo git pull, scp ou sftp para um host não confiável é um vetor. Cuidado redobrado com repositórios e mirrors de terceiros.
  • Servidores de aplicação com PHP ssh2. Se a sua aplicação usa ext-ssh2 para integrar com sistemas externos, cada conexão de saída é um ponto de contato.

O número que resume a gravidade é a nota CVSS 9.2: vetor de rede, baixa complexidade, sem necessidade de autenticação e impacto alto em confidencialidade, integridade e disponibilidade. Falhas pré-autenticação em bibliotecas onipresentes são exatamente o tipo de coisa que vira incidente em massa quando a prova de conceito já está pública, como está aqui.

Quando você não precisa entrar em pânico: máquinas que nunca iniciam conexões SSH de saída para hosts não confiáveis têm risco prático bem menor. O ataque exige que o seu cliente fale com um servidor malicioso. Ainda assim, atualizar continua sendo a resposta correta, porque o custo de corrigir é baixíssimo perto do custo de um runner comprometido.

Perguntas frequentes

A CVE-2026-55200 afeta o servidor SSH (o sshd) também?

Não diretamente. A falha está no lado cliente, no libssh2, que é a lib usada por quem se conecta. O OpenSSH server (sshd) é outra base de código. O alvo aqui é a sua máquina quando ela inicia a conexão, por isso runners e laptops são os mais expostos.

Eu não uso SSH no meu projeto. Ainda preciso me preocupar?

Provavelmente sim, de forma indireta. O libssh2 entra como dependência transitiva do curl e do Git. Mesmo sem usar SSH conscientemente, um git pull por SSH ou um curl para um endereço scp:// já aciona a lib. Rode a auditoria de versão para ter certeza.

Atualizar o libssh2 pode quebrar a minha aplicação?

O risco é baixo. A correção é um hardening pontual no parsing do pacote, sem mudança de API pública. Ainda assim, a regra de ouro vale: aplique primeiro em um ambiente de teste, rode a sua suíte e só então promova para produção.

Como faço para monitorar isso de forma contínua, sem depender de notícia?

Coloque um scanner de vulnerabilidade de dependências na pipeline (ferramentas como Trivy ou grype varrem imagens e reportam CVE conhecidas) e adicione o script de auditoria como um gate. Assim a esteira avisa você antes que a falha vire manchete.

Existe alguma mitigação se eu não puder atualizar agora?

Sim. Restrinja conexões SSH de saída a uma lista de hosts confiáveis, prefira clonar por https:// em vez de SSH em automações, e isole os runners de CI em rede segmentada. Essas medidas reduzem a chance de o seu cliente falar com um servidor malicioso, que é a condição necessária para o ataque.

Conclusão: três coisas para fazer ainda hoje

  • Audite agora. Rode os comandos de verificação no seu laptop, nos runners e dentro das imagens Docker. Versão 1.11.1 ou anterior é faixa vulnerável.
  • Corrija na raiz. Atualize o pacote do sistema e trave a versão corrigida no Dockerfile, para a falha não voltar no próximo build.
  • Automatize o gate. Coloque a verificação na pipeline para que a esteira falhe sozinha quando uma dependência vulnerável aparecer. É assim que os times sêniores dormem tranquilos.

Aliás, essa pergunta sobre como você descobre que uma dependência transitiva tem uma CVE crítica é uma das que mais separam o dev pleno do sênior em entrevista no mercado de hoje. Saber responder com um fluxo de auditoria e um gate de pipeline mostra maturidade de verdade.

Você já passou por um incidente de supply chain assim, com uma lib que ninguém lembrava de ter colocado no projeto? Conta nos comentários como vocês resolveram. Na próxima, vou mostrar como montar um scanner de CVE automático na pipeline com Trivy, do zero, falhando o build no nível certo de severidade.

Para se aprofundar em segurança de dependências, veja também nossos conteúdos sobre boas práticas de segurança em aplicações, como proteger pipelines de CI/CD e gestão de vulnerabilidades em dependências. A documentação oficial do projeto está em libssh2.org.