Olá a todos!
Estamos a chegar ao verão, portanto nada mais natural que o ruido dos carrosséis nas festas de verão – Para os meus leitores em outras geografias, em Portugal na altura do verão, existem as chamadas festas populares. Nessas festas populares, nos altifalantes dos carrosséis ouve-se bem alto que coloquem a moeda para dar mais uma volta…
Neste caso o mais uma moeda, mais uma volta refere-se a nova campanha de ataque que foi descoberta recentemente. O nome vem dos próprios investigadores da SafeDep e da Ox Security que a documentaram.
Se leram o meu post sobre o axios e a DPRK há umas semanas, lembram-se de como terminei: “O próximo axios está a acontecer. Pode ser esta semana. Pode já estar a acontecer enquanto escrevem o próximo npm install.” Pois bem. Não precisámos de esperar muito. E desta vez o bicho é maior. Literalmente. Chama-se Megalodon.
A 18 de Maio de 2026, numa janela de seis horas – das 11:36 às 17:48 UTC, um domingo – um atacante automatizou 5.718 commits maliciosos em 5.561 repositórios do GitHub. Não estamos a falar de repos obscuros com três estrelas e zero forks. Estamos a falar de repositórios como o Tiledesk (nove repos comprometidos), o Black-Iron-Project (oito repos), e centenas de outros projectos com pipelines de CI/CD activas, com developers reais, com código que vai para produção.
E o mais irritante? O atacante nem precisou de comprometer contas npm. Nem precisou de fazer account takeover. Envenenou os repositórios no GitHub, e os maintainers publicaram as versões maliciosas no npm sem perceber. O maintainer legítimo do Tiledesk publicou sete versões envenenadas – da 2.18.6 à 2.18.12 – porque o código malicioso estava no repositório e ele fez o que sempre fez: publicar a partir do source.
Antes de ir mais fundo, vou ser honesto: quando vi os números pela primeira vez, pensei que era exagero. Cinco mil e quinhentos repositórios? Num dia? Mas depois li a análise da SafeDep e da Ox Security, olhei para o CSV com os 5.718 commits, e não há como negar. Isto é real, é massivo, e é um sinal de alarme que a indústria não pode ignorar.
O que é o Megalodon e como funciona
A campanha foi documentada pela SafeDep e pela Ox Security, e a mecânica é elegante na sua simplicidade e terrível nas suas implicações.
O atacante criou contas descartáveis no GitHub com usernames aleatórios de oito caracteres — coisas como rkb8el9r, bhlru9nr, lo6wt4t6. Configurou o git config para forjar a identidade do autor com nomes como build-bot, auto-ci, ci-bot, ou pipeline-bot, associados a endereços como [email protected] e [email protected]. Nomes e emails que parecem perfeitamente normais num contexto de CI/CD. Quem é que olha duas vezes para um commit de um build-bot que diz “ci: add build optimization step”?
E foi exactamente isso que o atacante contou. Cada commit trazia uma de sete mensagens rotativas, todas a imitar manutenção de rotina de pipelines: “chore: optimize pipeline runtime”, “build: improve ci performance”, “fix: correct build workflow”, e variações do género. Todas perfeitamente banais. Todas desenhadas para passar despercebidas numa timeline de commits.
O payload propriamente dito? Um ficheiro YAML de GitHub Actions com um one-liner em base64 que, quando decodificado e executado, vira a pipeline de CI/CD numa máquina de exfiltração total. E quando digo total, quero dizer total.
A campanha usou duas variantes de payload. A variante de massa de nome SysDiag adiciona um workflow novo que dispara em cada push e pull request, maximizando a execução automática. A variante dirigida (targeted se preferirem) Optimize-Build —substitui workflows existentes com triggers workflow_dispatch, criando backdoors dormentes que o atacante pode activar quando quiser através da API do GitHub.
O que é que o malware rouba (spoiler: tudo)
A lista do que o Megalodon exfiltra lê-se como um inventário de “tudo o que um developer tem na máquina e no pipeline”. O payload vai buscar todas as variáveis de ambiente do CI, incluindo o /proc/*/environ e o ambiente do PID 1. Rouba chaves de acesso AWS – access keys, secret keys, session tokens – perfil por perfil, usando o CLI do AWS. Colhe tokens de acesso do Google Cloud via gcloud auth print-access-token. Consulta endpoints de metadata do AWS IMDSv2, do GCP, e do Azure para obter credenciais de instance role.
Mas não pára aí. Lê chaves SSH privadas. Configurações de autenticação Docker. Ficheiros .npmrc e .netrc. Configurações Kubernetes. Tokens Vault. Credenciais Terraform. Histórico de shell. Faz grep ao código fonte à procura de mais de 30 padrões regex de secrets — API keys, connection strings de bases de dados, JWTs, chaves PEM privadas, tokens de cloud.
E o detalhe que me impressionou porque claramente foi feito de forma pensada e rebuscada: exfiltra o URL e o token de OIDC request do GitHub Actions, o que permite ao atacante fazer impersonation da identidade cloud do developer. Pensem nisto: não só vos rouba as credenciais rouba a capacidade de se fazer passar por vós junto dos vossos cloud providers. Tudo isto empacotado num POST para um servidor C2 no IP 216.126.225.129 na porta 8443.
O investigador da Ox Security, Moshe Siman Tov Bustan, resumiu a situação de forma directa: considerar todas as variáveis de CI/CD comprometidas.
O caso Tiledesk: quando o GitHub é o vector e o npm é a vítima colateral
O caso do Tiledesk merece destaque separado porque ilustra um padrão que eu temo que se torne cada vez mais comum: o atacante não tocou na conta npm do maintainer. Não houve account takeover, não houve credential stuffing, não houve phishing para roubar o token de publicação. O atacante comprometeu o repositório no GitHub, provavelmente via um PAT (Personal Access Token) ou deploy key comprometida, e injectou o commit malicioso directamente no branch master, sem pull request, sem merge commit.
O maintainer legítimo – o mesmo que publicou a versão limpa 2.18.5 – fez o seu workflow habitual: puxou o código do repositório e publicou no npm. E pronto. Sete versões maliciosas publicadas pelo maintainer legítimo, a partir da sua conta legítima, com as suas credenciais legítimas. Nenhum alarme disparou no lado do npm porque, do ponto de vista do registry, era um publish normal de um maintainer autorizado.
Isto é o pesadelo da supply chain personificado. O modelo de confiança do npm assume que quem publica é quem diz ser e que o código é o que deveria ser. As duas premissas estavam correctas e o maintainer era mesmo ele, e o código era mesmo o do repositório. O problema é que o repositório tinha sido envenenado. E ninguém verificou. Não haviam mecanismos para o evitar in-place.
A relação com o TeamPCP — ou a falta dela
Uma pergunta que surge naturalmente é: isto é o TeamPCP outra vez? A resposta, pelo que a investigação da Ox Security indica, é provavelmente não. O estilo é semelhante – comprometer a cadeia de ferramentas para roubar credenciais – mas não há para já evidência de que o código ou a infraestrutura sejam os mesmos. A análise sugere um actor diferente a copiar o comportamento e o estilo, mas não o código propriamente dito.
E isto, na minha opinião, é pior do que se fosse o TeamPCP. Porquê? Porque significa que o modelo de ataque está a ser replicado. Há menos de dois meses, o TeamPCP era um grupo específico com um modus operandi particular. Agora temos pelo menos dois actores, possivelmente mais, a usar variações da mesma estratégia. O TeamPCP até abriu o código do seu worm Shai-Hulud no GitHub e anunciou uma competição de ataques de supply chain no BreachForums. A Ox Security acredita que o Megalodon não é uma entrada nessa competição (há regras específicas sobre chaves de encriptação para provar envolvimento), mas o simples facto de existir uma competição de supply chain attacks num fórum de cibercrime devia fazer-nos perder o sono a todos.
Bustan disse-o de forma que não deixa margem para interpretação: estamos numa nova era de ataques de supply chain, e o comprometimento do GitHub pelo TeamPCP foi apenas o acto de abertura. O que vem a seguir é uma vaga sem fim, um tsunami de ataques contra developers em todo o mundo.
Porque é que auditar dependências já não é opcional
E agora chegamos ao ponto que realmente me traz aqui, e que liga este post ao que escrevi sobre o axios e a ferramenta de supply chain monitoring da Elastic.
Quando escrevi sobre o axios, falei do monitor que o Joe Desimone da Elastic construiu numa tarde — aquele PoC que usa um LLM para analisar diffs de packages e detectar código malicioso. Falei de soak time, de lockfiles, de não puxar updates imediatamente. Falei de como a análise automatizada por LLM preenche uma lacuna real que existia entre a publicação de um package malicioso e a sua detecção.
O Megalodon reforça cada um desses pontos e adiciona uma camada de urgência que antes era teórica e agora é empírica.
Vejam: 5.561 repositórios comprometidos num dia. Sete versões de um package npm legítimo envenenadas. Zero alarmes no registry. O malware chegou ao npm não porque o registry falhou — chegou porque o modelo de confiança assume que o código no repositório é benigno. E isso, em 2026, é uma assunção que simplesmente não podemos continuar a fazer.
As ferramentas existem. Já vos mostrei como configurar o supply-chain-monitor-localai para monitorizar os top packages do npm e PyPI com um LLM local. Aquele monitor teria detectado as versões maliciosas do @tiledesk/tiledesk-server — o diff entre a 2.18.5 e a 2.18.6 mostra claramente a substituição de um workflow Docker legítimo por um one-liner base64 que executa um script de exfiltração. Não é subtil. É exactamente o tipo de mudança que um LLM apanha em segundos.
Mas o Megalodon levanta um problema adicional: o vector de ataque não foi o registry — foi o GitHub. E isso significa que precisamos de mecanismos de auditoria a operar em múltiplas camadas.
Camada 1: Auditar o que entra no vosso pipeline
Isto é o básico que já devia estar a funcionar. Lockfiles rigorosos. Soak time nas dependências. Monitorização activa dos packages que usam. O npm config set min-release-age 7 que mencionei no post do axios. O supply-chain-monitor-localai a correr contra os vossos packages críticos. SBOMs actualizados.
Se ainda não fizeram nada disto, o Megalodon é o mais um wake-up call. Não é uma questão de se serão afectados. É uma questão de quando. O ecossistema npm publica centenas de milhares de novas versões por semana. O PyPI também. A proporção maliciosa pode ser pequena em termos percentuais, mas em números absolutos são centenas de packages por mês. E a tendência é claramente de crescimento.
Camada 2: Auditar o que acontece nos vossos repositórios
E esta é a camada que o Megalodon expõe como insuficiente na maioria das organizações. O atacante não precisou de comprometer o npm. Comprometeu os repositórios Git e deixou que o fluxo normal de publicação fizesse o resto.
Quantos de vocês têm alertas configurados para commits directos ao branch principal sem pull request? Quantos verificam se os commits são assinados? Quantos monitorizam mudanças em ficheiros de workflow (.github/workflows/)? Quantos têm branch protection rules que impedem pushes directos ao main/master?
O Megalodon explorou precisamente a ausência destes controlos. Commits directos ao master, sem PR, sem code review, sem assinatura GPG, com identidades de autor forjadas que parecem bots de CI legítimos. Se tivessem branch protection com exigência de PR e aprovação, o commit do build-bot teria sido rejeitado. Se tivessem exigência de commits assinados, o commit com um email noreply.dev de uma conta descartável teria falhado a verificação.
Estas não são medidas exóticas. São funcionalidades nativas do GitHub que a maioria dos repositórios não tem activadas. E o custo de não as activar acabou de ficar dramaticamente claro.
Camada 3: Auditar a identidade e os acessos
Os PATs (Personal Access Tokens) e deploy keys são a jóia da coroa para atacantes de supply chain. O Megalodon quase certamente usou PATs ou deploy keys comprometidas para fazer push dos commits maliciosos. A pergunta é: de onde vieram essas credenciais?
Pode ter sido de leaks anteriores. Pode ter sido da cascata Trivy → LiteLLM → Telnyx que descrevi no post do axios. Pode ter sido do próprio breach do GitHub pelo TeamPCP, que exfiltrou ~3.800 repositórios internos e potencialmente expôs mecanismos internos de autenticação. As fontes possíveis são múltiplas — e essa é exactamente a questão.
Auditar os PATs que existem na vossa organização, revogar os que não são necessários, implementar rotação regular, exigir scopes mínimos, e monitorizar a actividade de tokens é tão importante como auditar as dependências que instalam. De nada serve ter lockfiles perfeitos se o vosso PAT com permissão de escrita no repositório principal está comprometido.
O que devem fazer, concretamente
Vou ser prático como sempre:
Activem branch protection no vosso branch principal. Exijam pull requests com pelo menos uma aprovação para qualquer merge. Proíbam pushes directos. Isto teria bloqueado o Megalodon. É uma configuração de dois minutos no GitHub.
Exijam commits assinados. O GitHub suporta verificação de commits via GPG, SSH, ou S/MIME. Commits de um [email protected] sem assinatura verificável teriam sido imediatamente identificados como suspeitos.
Monitorizem mudanças em ficheiros de workflow. O directório .github/workflows/ é um alvo de alto valor. Qualquer mudança num ficheiro YAML de workflow devia gerar um alerta e exigir review explícita de alguém da equipa de segurança ou DevOps. Existem GitHub Actions específicas para isto — usem-nas.
Auditem os vossos PATs e deploy keys. Vão às settings da vossa organização no GitHub, listem todos os tokens activos, verifiquem os scopes, revoguem tudo o que não é estritamente necessário. Implementem rotação trimestral no mínimo.
Implementem soak time nas dependências. Se ainda não o fizeram, aqui vai outra vez:
npm config set min-release-age 7
Sete dias antes de aceitar um novo release. Dá tempo à comunidade e a ferramentas de monitorização para detectar compromises antes que cheguem ao vosso pipeline.
Corram o supply-chain-monitor-localai. Já vos mostrei como no post do axios. Se têm um servidor LLM a correr e se leram os meus posts sobre Ollama e modelos locais, provavelmente têm, a integração é trivial. Apontem o --base-url para o vosso endpoint e deixem-no a monitorizar os packages do vosso stack.
Não confiem cegamente em nenhum marketplace, registry, ou plataforma. Não no npm, não no PyPI, não no GitHub Actions marketplace, não no VS Code marketplace. O Megalodon envenenou repositórios GitHub. O TeamPCP usou extensões VS Code. O ataque ao axios usou account takeover no npm. O Shai-Hulud propaga-se como um worm. Cada ecosistema é um vector. A vossa postura de segurança precisa de assumir que qualquer um deles pode ser comprometido a qualquer momento.
O padrão que se repete e repete e repete e repete
Vou dizer isto da forma mais directa que consigo: estamos a assistir à industrialização por AI dos ataques de supply chain. O que em 2024 era um ataque sofisticado e raro, o XZ Utils, o event-stream, em 2026 é uma commodity. O TeamPCP abriu o código do Shai-Hulud. Há competições de supply chain attacks em fóruns de cibercrime. O Megalodon infectou mais de cinco mil repos num domingo à tarde.
A barreira de entrada para estes ataques baixou. As ferramentas estão disponíveis. Os vectores estão documentados. E os mecanismos de defesa da maioria das organizações estão anos atrás da realidade actual.
Já escrevi sobre o axios. Sobre o breach do GitHub pelo TeamPCP. Sobre o BitwardenGate. Sobre a cascata Trivy → LiteLLM → Telnyx. Cada um destes posts tem um tema comum: a confiança implícita que depositamos em infraestrutura e ecossistemas de terceiros está a ser explorada de forma sistemática, e a velocidade e a escala dos ataques estão a aumentar e acreditem que isto ainda é só o começo.
O Megalodon é mais um capítulo e garantidamente não será o último. O Bustan da Ox Security chamou-lhe o início de um tsunami. Concordo. E a única forma de sobreviver a um tsunami é estar preparado antes dele chegar. Preparem as vossas pranchas! Surfem a onda para não acabarem afogados por ela.
Auditem as vossas dependências. Protejam os vossos repositórios. Monitorizem os vossos pipelines. Não esperem pelo próximo post a dizer-vos que o package X foi comprometido.Quando eu escrever esse post, o malware já vai ter corrido nos vossos sistemas durante dias.
Mantenham-se vigilantes.
Um abraço,
Nuno
Fontes:
- The Register — Megalodon chums the waters in 5.5K+ GitHub repo poisonings (22 Maio 2026)
- SafeDep — Megalodon: Mass GitHub Repo Backdooring via CI Workflows (21 Maio 2026)
- Ox Security — Megalodon: New CI/CD Malware Spreads Across GitHub, Infecting ~5,000+ Repositories (21 Maio 2026)
- Este blog — Axios, DPRK, e um PoC feito numa tarde (14 Abril 2026)
- Este blog — O GitHub foi hackeado por uma extensão de VS Code envenenada (20 Maio 2026)
