Shopping cart

Subtotal $0.00

View cartCheckout

Building better devs

TnewsTnews
  • Home
  • Notícias
  • Seu composer install Pode Ter Roubado Todas as Suas Senhas
Notícias

Seu composer install Pode Ter Roubado Todas as Suas Senhas

Email : 14

Um composer install que vira pesadelo

Imagine a cena: você roda composer install no seu projeto Laravel, como faz todo dia. O terminal mostra os pacotes sendo baixados, tudo normal. Você toma seu café, abre o VS Code e começa a codar. O que você não sabe é que, nos últimos 30 segundos, um script PHP de quase 6.000 linhas varreu seu computador inteiro — chaves SSH, credenciais AWS, tokens do GitHub, carteiras de criptomoedas, senhas salvas no Chrome, vaults do 1Password e até seus cookies do Discord. Tudo criptografado com AES-256 e enviado para um servidor na internet.

Paranoia? Não. Isso aconteceu de verdade, em 22 de maio de 2026, com pelo menos 233 versões de pacotes do ecossistema Laravel-Lang.

O que é o Laravel-Lang e por que isso importa

O Laravel-Lang é um conjunto de pacotes de tradução e localização mantidos pela comunidade. Se você já usou laravel-lang/lang (7.800 stars no GitHub), laravel-lang/attributes, laravel-lang/http-statuses ou laravel-lang/actions, seus projetos dependem desse ecossistema.

São pacotes “inofensivos” — arquivos de tradução, basicamente. Ninguém audita pacote de tradução com o mesmo cuidado que audita uma lib de autenticação. E é exatamente por isso que o atacante escolheu esse alvo.

“A supply chain attack doesn’t need to compromise the most critical package. It just needs to compromise the most trusted one.”

— Pesquisadores da Aikido Security

Como o ataque funcionou (passo a passo)

O vetor de ataque é engenhoso e explora uma feature pouco conhecida do GitHub: tags de versão podem apontar para commits de forks. O atacante não precisou invadir o repositório oficial. Ele fez um fork, adicionou código malicioso, e criou tags no repositório original apontando para commits do fork.

Passo 1: Fork silencioso

O atacante criou um fork dos repositórios do Laravel-Lang. Nesse fork, adicionou um arquivo src/helpers.php com duas funções que parecem legítimas:


function laravel_lang_locale() {
    return config('app.locale', 'en');
}

function laravel_lang_fallback() {
    return config('app.fallback_locale', 'en');
}

// Abaixo das funções "legítimas", o código malicioso
// que se auto-executa via bloco IIFE
(function() {
    $marker = sys_get_temp_dir() . '/.laravel_locale/' . md5(__FILE__ . gethostname());
    if (file_exists($marker)) return;
    // ... dropper code
})();

Passo 2: Tags envenenadas

Usando credenciais de nível organizacional (possivelmente obtidas via leak ou phishing), o atacante publicou 233 tags de versão nos repositórios oficiais, todas apontando para commits no fork malicioso. Mais de 700 versões foram publicadas em questão de segundos — um padrão que deveria ter acionado alertas, mas não acionou.

Passo 3: Composer autoload faz o trabalho sujo

O arquivo src/helpers.php foi registrado em composer.json sob autoload.files. Isso significa que qualquer aplicação PHP que execute require __DIR__.'/vendor/autoload.php' — ou seja, literalmente toda aplicação Laravel — carrega o código malicioso automaticamente.

Sem precisar instanciar uma classe. Sem chamar um método. Só de dar boot na aplicação, o stealer já está rodando.

Passo 4: Fingerprint e persistência

O dropper gera um hash MD5 único combinando o caminho do arquivo, hostname e inode do sistema. Um arquivo marcador é criado em /.laravel_locale/ para garantir que o payload executa apenas uma vez por máquina. Esperto: se rodasse toda vez, seria detectado mais rápido.

Passo 5: Payload específico por plataforma

O domínio de C2 (flipboxstudio[.]info) estava ofuscado dentro de um array de inteiros — nada de strings em texto claro para scanners acharem. O dropper busca o payload via file_get_contents com fallback para curl, ambos com verificação SSL desabilitada (red flag clássico):

  • Windows: Baixa um launcher .vbs executado via cscript
  • Linux/macOS: Executa direto em background via exec()

O stealer: 5.900 linhas de destruição organizada

O payload final é um arquivo PHP de quase 6.000 linhas, dividido em 15 módulos especializados. Cada módulo sabe exatamente onde procurar credenciais em cada sistema operacional. Depois de coletar tudo, encripta com AES-256 e envia para flipboxstudio[.]info/exfil. Então se auto-deleta.

A tabela abaixo mostra o que cada módulo rouba:

Módulo O que rouba Onde procura
——– ———— ————–
Cloud AWS Access keys, secret keys, session tokens ~/.aws/credentials, variáveis de ambiente, EC2 metadata
Cloud GCP Application default credentials ~/.config/gcloud/, CLI configs
Cloud Azure Access tokens, service principals Azure CLI cache, environment
Cloud Misc Tokens DigitalOcean, Heroku, Vercel, Netlify, Railway, Fly.io Configs locais de cada CLI
CI/CD Tokens Jenkins, GitLab Runner, GitHub Actions, CircleCI, TravisCI, ArgoCD Variáveis de ambiente, configs
Kubernetes Kubeconfig, service account tokens, Helm configs ~/.kube/, /var/run/secrets/
SSH/Git Chaves privadas, git-credentials, .netrc, shell history ~/.ssh/, ~/.gitconfig, ~/.bash_history
Package Managers .npmrc, .pypirc, .gem/credentials, composer/auth.json Home directory
Browsers (Chromium) Senhas, cookies, histórico de 17 browsers Chrome, Edge, Brave, Opera, Vivaldi, Yandex
Browsers (Firefox) Databases de senhas Firefox, Thunderbird
Password Managers Vaults do 1Password, Bitwarden, LastPass, KeePass, Dashlane, NordPass Paths conhecidos de cada app
Crypto Wallets Seeds e chaves de Bitcoin, Ethereum, Monero + 7 outros Electrum, Exodus, Atomic, Ledger Live, Trezor, Wasabi, Sparrow
Crypto Extensions Dados de extensões de browser MetaMask, Phantom, Trust Wallet, Ronin, Keplr, Solflare, Rabby
VPN Configs e credenciais NordVPN, ExpressVPN, ProtonVPN, CyberGhost, Mullvad, Surfshark, WireGuard, OpenVPN
Windows Specific Credential Manager, sessões PuTTY/WinSCP, arquivos .rdp, perfis Outlook Registry, AppData

Eu já vi malware comercial com menos funcionalidade que isso. O stealer inclui até um executável embeddado para Windows que bypassa a criptografia app-bound do Chromium — aquela proteção que o Chrome adicionou justamente para impedir que malware leia senhas salvas.

O detalhe mais assustador: ambientes de CI/CD

A maioria das análises foca no roubo de credenciais de desenvolvedores individuais. Mas pensa no cenário real: quantos pipelines de CI/CD rodam composer install automaticamente a cada push?

Se um GitHub Action, GitLab Runner ou Jenkins pipeline instalou uma versão comprometida, o stealer teve acesso a:

  • Service account tokens do Kubernetes
  • Secrets injetados como variáveis de ambiente
  • Deploy keys com permissão de escrita
  • Tokens de API de serviços de produção

Um único pipeline comprometido pode significar acesso completo à infraestrutura de produção de uma empresa. E o stealer se auto-deleta depois, então boa sorte encontrando evidências no runner efêmero que já foi destruído.

Como saber se você foi afetado

Verificação rápida


# Checar se existe o diretório marcador
ls -la /tmp/.laravel_locale/ 2>/dev/null

# No macOS
ls -la $TMPDIR/.laravel_locale/ 2>/dev/null

# Verificar composer.lock por versões suspeitas
grep -E "laravel-lang/(lang|attributes|http-statuses|actions)" composer.lock

Se o diretório .laravel_locale existir no seu temp, seu sistema foi infectado.

Verificação no composer.lock

Abra seu composer.lock e procure os pacotes afetados. Compare o hash do commit referenciado com os commits legítimos do repositório oficial. Se o reference aponta para um commit que não existe no repositório principal (apenas no fork), você instalou uma versão maliciosa.

Monitorar conexões de rede


# Verificar conexões para o C2
# (provavelmente já não está mais ativo, mas vale checar logs)
grep -r "flipboxstudio" /var/log/ 2>/dev/null

# Checar DNS queries recentes
grep "flipboxstudio" /var/log/syslog 2>/dev/null

Indicadores de Comprometimento (IOCs)

Tipo Valor
—— ——-
Domínio C2 flipboxstudio[.]info
Endpoint de payload flipboxstudio[.]info/payload
Endpoint de exfiltração flipboxstudio[.]info/exfil
Diretório marcador /.laravel_locale/
Arquivo stealer /.laravel_locale/.php
Launcher Windows /.laravel_locale/.vbs

O que fazer agora (plano de resposta)

Se você usa qualquer pacote do Laravel-Lang, siga esses passos na ordem:

1. Verifique suas versões instaladas


composer show laravel-lang/* 2>/dev/null

2. Atualize para versões limpas

O Packagist removeu as versões maliciosas. Rode:


composer update laravel-lang/*

3. Rode o scan de IOCs

Verifique se os marcadores de infecção existem no seu sistema (comandos acima).

4. Se infectado: rotacione TUDO

Não tem meio termo aqui. Se o marcador existir, considere que todas as credenciais do sistema foram comprometidas:

  • Chaves SSH: gere novas e revogue as antigas
  • Tokens AWS/GCP/Azure: rotacione imediatamente
  • Tokens de CI/CD: regenere todos
  • Senhas de banco: troque
  • API keys: revogue e recrie
  • Carteiras crypto: transfira fundos para carteiras novas AGORA
  • Senhas do browser: troque todas as senhas importantes
  • Vault do password manager: troque a master password e rotacione entries críticas

5. Audite seus pipelines

Verifique os logs de todos os pipelines que rodaram composer install desde 22 de maio. Se algum instalou versões afetadas, trate o ambiente de CI/CD como comprometido.

O problema estrutural que ninguém quer discutir

Esse ataque expõe um problema fundamental do ecossistema de pacotes: confiança transitiva sem verificação.

Quando você roda composer require laravel-lang/lang, está dizendo “eu confio nesse mantenedor”. Justo. Mas quando o Composer resolve dependências e autoloads, você também está confiando em:

  • A infraestrutura do GitHub (tags, forks, referências)
  • O Packagist (resolução de versões)
  • Todos os scripts de autoload de todas as dependências transitivas
  • Que nenhum desses pontos foi comprometido


Sua aplicação
    └── laravel/framework (confiável? sim)
         └── laravel-lang/lang (confiável? era...)
              └── autoload.files → helpers.php (malicioso!)

O Composer não tem nenhum mecanismo nativo de sandboxing para autoloaded files. Um pacote de tradução roda com os mesmos privilégios que seu framework. E o autoload.files do composer.json executa código arbitrário no boot da aplicação sem nenhum aviso.

Isso não é bug do Composer — é um design decision que prioriza conveniência sobre segurança. E todo gerenciador de pacotes moderno tem variações do mesmo problema: npm com postinstall, pip com setup.py, Ruby com gemspec hooks.

Lições para se proteger no futuro

Lock files são seus amigos (de verdade)

O composer.lock fixa não só a versão, mas o hash exato do commit. Se você commita o lock file e faz composer install (não update) no CI, versões novas não entram automaticamente. Mas quantos projetos fazem composer update direto no pipeline?

Monitore publicações de pacotes

Ferramentas como o Aikido Security, Socket e StepSecurity monitoram publicações suspeitas — como 233 tags publicadas em segundos. Integre essas ferramentas no seu pipeline.

Princípio do menor privilégio no CI/CD

Seu pipeline de CI/CD precisa de acesso à AWS de produção para rodar testes unitários? Provavelmente não. Separe pipelines de teste (sem credenciais sensíveis) de pipelines de deploy (com credenciais mínimas e temporárias).


# GitHub Actions - pipeline de teste SEM credenciais
test:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - run: composer install
    - run: php artisan test
  # Sem secrets injetados!

# Pipeline de deploy com credenciais mínimas
deploy:
  needs: test
  runs-on: ubuntu-latest
  permissions:
    id-token: write  # OIDC, sem long-lived keys
  steps:
    - uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: arn:aws:iam::role/deploy-only

Audite o que está no autoload

Dê uma olhada no vendor/composer/autoload_files.php do seu projeto. Cada arquivo listado ali executa código automaticamente quando sua aplicação inicia. Quantos deles você realmente conhece?


# Listar todos os arquivos de autoload
cat vendor/composer/autoload_files.php | grep "'"

O atacante vai ser pego?

O domínio flipboxstudio[.]info é uma referência ao Flipbox Studio, uma empresa legítima de desenvolvimento Laravel na Indonésia. Provavelmente escolhido de propósito para parecer legítimo em logs superficiais. O registro do domínio certamente usa informações falsas ou um proxy de privacidade.

A velocidade e sofisticação do ataque — 15 módulos de coleta, suporte multi-plataforma, criptografia AES-256, auto-deleção — sugere que não é um script kiddie experimentando. É trabalho profissional, possivelmente de um grupo organizado que já fez isso antes com outros ecossistemas.

O Packagist reagiu rápido e removeu as versões maliciosas. Mas o estrago para quem instalou nas primeiras horas? Já está feito. As credenciais já foram exfiltradas.

A real sobre supply chain attacks

Eu tenho uma teoria impopular: supply chain attacks em pacotes open source vão piorar muito antes de melhorar. Os incentivos estão todos desalinhados:

  • Mantenedores de pacotes populares frequentemente trabalham de graça, sem recursos para segurança avançada
  • Gerenciadores de pacotes priorizam UX sobre security by default
  • Desenvolvedores confiam cegamente em install e update sem auditar mudanças
  • CI/CD pipelines rodam com privilégios excessivos por conveniência

Até que o ecossistema inteiro mude — com provenance verification obrigatória, sandboxing de pacotes, e assinatura criptográfica de releases — ataques como esse vão continuar acontecendo. A questão não é se, mas quando o próximo vai aparecer.

Enquanto isso, vai lá rodar aquele ls -la /tmp/.laravel_locale/ e torcer para o diretório não existir.

Fonte de inspiração: Aikido Security — Supply Chain Attack Targets Laravel-Lang Packages e The Hacker News — Laravel-Lang PHP Packages Compromised

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts