← Todas as verificações
SegurançaSeveridade típica: Baixo

Manifestos de dependências expostos

Deteta ficheiros package.json ou composer.json acessíveis que revelam as tuas dependências e versões exatas.

O que verifica

Este scanner verifica se ficheiros de manifesto de dependências como package.json ou composer.json são acessíveis publicamente no teu site. Deteta quando ficam servidos e revelam a lista de bibliotecas que usas e as suas versões exatas.

Porque importa

Conhecer as tuas dependências e versões exatas facilita a um atacante procurar vulnerabilidades públicas que afetem justamente o que usas. É trabalho de reconhecimento que lhe poupas e que delimita bastante por onde tentar atacar o teu site.

Como se corrige

Garante que estes ficheiros de manifesto não são servidos a partir da pasta pública; normalmente devem ficar na raiz do projeto, não na pasta web. Bloqueia o seu acesso na configuração do teu servidor ou do CDN se a tua framework os expõe por omissão.

Como funciona esta verificação

O Scanaris pede dois ficheiros na raiz do teu domínio: /package.json, o manifesto de um projeto Node, e /composer.json, o de um projeto PHP. Para cada um, dá o achado por confirmado só se responder 200, o corpo não for HTML, for JSON válido e contiver as chaves próprias do manifesto: dependencies ou devDependencies no primeiro, require ou require-dev no segundo. Assim não marca uma aplicação de página única que devolve o seu HTML para qualquer rota, nem um JSON qualquer que por acaso viva ali. Cada ficheiro encontrado abre um achado de severidade baixa.

Porque importa

Estes ficheiros não contêm segredos, mas contêm algo quase tão útil para um atacante: a lista exata de bibliotecas que usas e as suas versões. Com isso não tem de adivinhar nada: cruza a tua lista com a base de dados de vulnerabilidades conhecidas e sabe que exploit testar e contra o quê. Também revelam o nome interno do projeto, os scripts de build e deploy, por vezes o URL do repositório privado e os nomes de pacotes internos da tua organização, que são o ponto de partida dos ataques de confusão de dependências. É severidade baixa porque é informação, não acesso; mas é informação que ofereces sem motivo.

Porque acontece

Porque o servidor web serve a pasta inteira do projeto em vez da pasta de saída. Um Vite, Nuxt ou Next.js bem implantados só publicam dist/, .output/public/ ou .next/static/, e aí não há package.json. Aparece quando se envia o repositório completo por FTP para public_html, quando o diretório raiz de um alojamento estático aponta para a raiz do projeto, ou em projetos PHP onde o composer.json está no mesmo diretório que o index.php, o que é habitual no WordPress com Composer e em instalações feitas à mão.

Como corrigir

  • Serve só a pasta pública. No Vercel e no Netlify, revê o "output directory" ou "publish directory" do projeto; deve ser a pasta de build, não .. No nginx e no Apache, o root ou DocumentRoot aponta para public/ ou dist/.
  • Em PHP, move o composer.json, o composer.lock e a vendor/ um nível acima do diretório público se a tua framework o permitir (o Laravel e o Symfony já o fazem). Se não os puderes mover, bloqueia-os:
location ~* /(package|composer)(-lock)?\.json$ { return 404; }
location ~* /(yarn|pnpm-lock)\.(lock|yaml)$ { return 404; }
  • No Apache, um <FilesMatch "^(package|composer)(-lock)?\.json$"> Require all denied </FilesMatch> na configuração ou no .htaccess.
  • Revê o que mais foi enviado. Onde há um package.json público costuma haver um .env, um .git/ ou um composer.lock ao lado; a verificação de ficheiros sensíveis procura os graves.

Confirma que está corrigido

for p in package.json composer.json package-lock.json composer.lock yarn.lock; do
  printf "%-20s " "$p"; curl -s -o /dev/null -w "%{http_code} %{content_type}\n" "https://teudominio.com/$p"
done

Esperado: 404 ou 403. Um 200 com text/html é o HTML genérico de uma aplicação de página única e não é problema; um 200 com application/json é o ficheiro real.

Perguntas frequentes

O meu repositório é público no GitHub de qualquer forma.

Então o manifesto já é público e este achado não acrescenta exposição nova; podes dá-lo por aceite. Mesmo assim, corrigir a raiz do servidor evita que o próximo ficheiro que caia na pasta do projeto seja publicado sem querer.

E os lockfiles?

Esta verificação olha para os dois manifestos, mas package-lock.json, yarn.lock e composer.lock são piores: listam todas as dependências transitivas com versão exata. Se o manifesto está exposto, quase de certeza que o lockfile também; a regra de bloqueio de cima cobre-os.

Se não servir o manifesto, ninguém sabe que versões uso?

Podem deduzi-lo por outros meios, mais lentos: cabeçalhos, caminhos dos bundles, comportamento. O que bibliotecas desatualizadas deteta no teu JavaScript, por exemplo, vê-o qualquer um. Esconder o manifesto tira o atalho; atualizar as dependências tira o problema.

Verifica-o no teu site

Analisa o teu site grátis e vê se esta e outras 44 verificações passam, com um fix prompt por cada problema.

Analisar o meu site grátis

Verificações relacionadas