🔑 Resumo principal
Por meio de uma vulnerabilidade de dependência no Trivy, tokens de API foram roubados e, a partir disso, versões maliciosas dos pacotes litellm e telnyx foram publicadas no PyPI. O malware era executado imediatamente após a instalação, coletava credenciais e arquivos sensíveis e depois os exfiltrava para um servidor externo.
⚠️ Por que este malware é especial
A maioria dos pacotes maliciosos no PyPI até agora eram pacotes recém-criados (como typosquatting). Este ataque foi diferente. Ele injeta código malicioso em pacotes de código aberto já amplamente usados.
Há dois caminhos de injeção:
- atacar diretamente projetos open source com repositórios, workflows de release ou autenticação fragilizados
- roubar tokens de API e chaves em máquinas de desenvolvedores que instalam a versão mais recente
Com tokens de API do PyPI ou GitHub roubados, a estrutura do ataque permite uma cadeia de comprometimentos que invade outros pacotes open source.
📅 Linha do tempo do incidente
LiteLLM
Foi baixado mais de 119.000 vezes durante o período em que a versão maliciosa ficou exposta.
O PyPI recebeu 13 denúncias por meio do recurso de "denúncia de malware".
| Etapa | Tempo decorrido |
|---|---|
| Upload → primeira denúncia | 1h 19min |
| Primeira denúncia → quarentena | 1h 12min |
| Tempo total de exposição | 2h 32min |
O LiteLLM é instalado cerca de 15 a 20 milhões de vezes por semana, com aproximadamente 1.700 instalações por minuto. Destas, cerca de 40% a 50% não tinham versão fixada e recebiam automaticamente a versão mais recente.
Telnyx
O pacote telnyx foi automaticamente colocado em quarentena graças ao sistema de trusted reporters do PyPI.
| Etapa | Tempo decorrido |
|---|---|
| Upload → primeira denúncia | 1h 45min |
| Primeira denúncia → quarentena | 1h 57min |
| Tempo total de exposição | 3h 42min |
🛡️ Recomendações de segurança para desenvolvedores
1. Cooldown de dependências (Dependency Cooldowns)
É uma estratégia para configurar o ambiente de modo que pacotes publicados recentemente não sejam instalados por um período determinado, dando tempo para pesquisadores de segurança e administradores do PyPI reagirem.
uv — suporte disponível atualmente:
# ~/.config/uv/uv.toml ou pyproject.toml
[tool.uv]
exclude-newer = "P3D" # exclui pacotes publicados nos últimos 3 dias
pip v26.1 — suporte previsto para abril:
# ~/.config/pip/pip.conf
[install]
uploaded-prior-to = P3D
⚠️ Cooldown não é solução mágica. Se for necessário aplicar um patch de segurança, ele deve ser instalado imediatamente, então é preciso usar junto ferramentas de varredura de vulnerabilidades como Dependabot e Renovate.
2. Travamento de dependências (Lock Files)
Registrar apenas versões com pip freeze não é um lock file. Para segurança, é necessário um lock file de verdade, com checksum/hash incluído.
Ferramentas recomendadas:
uv lockpip-compile --generate-hashespipenv
🔒 Recomendações de segurança para mantenedores de open source
1. Reforçar a segurança do workflow de release
- Não usar gatilhos inseguros —
pull_request_targetdo GitHub Actions é especialmente arriscado - Sanitizar parâmetros e entradas — passe via variáveis de ambiente para evitar template injection
- Não usar referências mutáveis — use commit SHA em vez de tags Git e mantenha lock files de dependências
- Exigir revisão para deploys — use Trusted Publishers + GitHub Environments para exigir aprovação adicional na publicação
Se você usa GitHub Actions, é recomendável verificar vulnerabilidades do workflow com a ferramenta Zizmor.
2. Usar Trusted Publishers em vez de tokens de API
- Tokens de API têm longa duração, então, se forem roubados, é difícil detectar o uso de imediato
- Trusted Publishers usam tokens de curta duração, o que reduz o risco porque, mesmo roubados, precisam ser usados imediatamente
- Com Digital Attestations, usuários downstream conseguem detectar publicações que não passaram pelo workflow legítimo de release
3. Tornar 2FA obrigatório
O PyPI tornou 2FA obrigatório para publicação de pacotes a partir de 2024. Mas é preciso aplicar 2FA (de preferência com chave de hardware) não só na conta do PyPI, mas em todas as contas relacionadas ao desenvolvimento open source, como GitHub, GitLab e e-mail.
💰 Como apoiar esta atividade
As atividades de segurança do PyPI são possíveis graças ao apoio da Python Software Foundation (PSF). Você pode contribuir pelo programa de patrocínio da PSF, fazer uma doação direta ou entrar em contato por sponsors@python.org.
Os cargos de engenheiros de segurança do PyPI de Mike Fiedler e Seth Larson são financiados pela Alpha-Omega.
1 comentários
Criei um servidor MCP e publiquei no npm, então esse relatório do incidente foi bem assustador.
No fim das contas, os servidores MCP também vão direto para npm e PyPI, e há muitos casos em que são instalados sem fixar versão; além disso, ainda não existem coisas como um sistema de denúncia ou
trusted publisher. O LiteLLM ficou exposto por pouco mais de 2 horas, mas, vendo esse volume de downloads, fiquei com a sensação de que, se algo assim entrar nesse ecossistema, pode permanecer por bastante tempo.Pelo que vi, no lado do Claude Code também há casos em que essas configurações de proteção não são aplicadas corretamente no
pip install, então, se o fluxo for de um agente instalar pacotes por conta própria, fica meio nebuloso em que ponto isso deveria ser bloqueado.