Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
sloppy-joe — Protege contra ataques de supply-chain, slopsquatting e typosquatting provenientes de dependências e código. | Kitploit
Ferramentas/GitHubGitHub/brennhill/sloppy-joe
Análise EstáticaScanners de VulnerabilidadesAnálise de CódigoDevSecOpsDetecção de SegredosInteligência de AmeaçasSegurança da Cadeia de SuprimentosAprendizado e Educação
GitHubbrennhill/sloppy-joe

sloppy-joe

Protege contra ataques de supply-chain, slopsquatting e typosquatting provenientes de dependências e código.

Ver Repositório
3213há 4 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

sloppy-joe

Capture dependências alucinadas, com typosquatting e não canônicas
antes que cheguem à produção.

cargo install sloppy-joe


O ataque à cadeia de suprimentos do LiteLLM (março de 2026) comprometeu um pacote com 97 milhões de downloads mensais. Atacantes roubaram credenciais de publicação, enviaram versões maliciosas que coletaram chaves SSH, credenciais de nuvem e segredos do K8s. O bloqueio padrão de 72 horas do sloppy-joe teria impedido ambas as versões envenenadas — elas foram descobertas em horas, muito antes da liberação. Se você executar sloppy-joe check na CI, esse ataque falha. Análise completa

Geradores de código de IA alucinam nomes de pacotes ~20% das vezes. Atacantes registram esses nomes e esperam. O sloppy-joe os captura na CI antes de npm install ou ser executado.

pip install

Como Usar```bash

Install (single static binary, no runtime dependencies)

cargo install sloppy-joe

Or download an auditable binary archive from GitHub Releases

https://github.com/brennhill/sloppy-joe/releases

Fast local guardrail — auto-detects ecosystem from manifest files

sloppy-joe check

Strict online scan (recommended before push / release)

sloppy-joe check --full

Strict CI-oriented scan

sloppy-joe check --ci

Check a specific directory

sloppy-joe check --dir ./my-project

Check only npm dependencies

sloppy-joe check --type npm

Check the Python runtime plus selected groups/extras

sloppy-joe check --python-groups dev,test --python-version 3.12 sloppy-joe check --python-extras docs --python-platform linux --python-version 3.12

Enforce canonical rules and org standards via config

sloppy-joe check --config /etc/sloppy-joe/config.json

Config from a URL (useful in CI — no secrets to manage)

sloppy-joe check --config https://raw.githubusercontent.com/yourorg/security-configs/main/sloppy-joe.json

JSON output for CI pipelines

sloppy-joe check --json

Review exact maintainer-change exceptions with evidence

sloppy-joe check --review-exceptions

Create and register a safe per-repo config outside the repo

sloppy-joe init --register

Create an ecosystem-specific greenfield starter policy

sloppy-joe init --greenfield --ecosystem npm

Print review-only bootstrap suggestions for an npm or Cargo repo

sloppy-joe init --from-current

Or write/register those suggestions safely outside the repo

sloppy-joe init --from-current --register

Or write a config manually to a secure path outside the repo

sloppy-joe init > /secure/location/sloppy-joe.json

root@kitploit:~
### Nix```bash
nix profile install github:brennhill/sloppy-joe

Modos de verificação:

  • sloppy-joe check executa o guardrail local rápido. Ele sempre impõe análise de manifesto, lockfile/sincronização, proveniência e política de fontes não suportadas. Se o estado da dependência ou política mudou, ou a última verificação completa bem-sucedida tem mais de 24 horas, ele recomenda sloppy-joe check --full.
  • sloppy-joe check --full executa a verificação online rigorosa e atualiza o estado registrado da verificação completa bem-sucedida.
  • sloppy-joe check --ci executa a mesma cobertura rigorosa que --full, com intenção orientada a CI.
  • Para Python, sloppy-joe check avalia o perfil runtime por padrão. Se existirem dependências com escopo, ele avisa e informa para passar flags explícitas --python-groups, --python-extras, --python-platform e/ou --python-version para paridade de CI/build.
  • A saída legível por humanos do sloppy-joe check sempre lembra você de usar --ci ou --full para bloqueio em CI e produção.

Códigos de saída: 0 = nenhum problema bloqueante encontrado no modo selecionado, 1 = problemas bloqueantes encontrados, 2 = erro de execução.

Compatível com: JavaScript (npm, pnpm, Yarn, Bun), Python, Rust, Go, Ruby, PHP, JVM (Gradle/Maven) e .NET — detectado automaticamente a partir dos arquivos de manifesto.

Guias de ecossistemas: consulte docs/ecosystems/README.md para o modelo de confiança atual, recursos suportados e limites de falha fechada para cada ecossistema.

  • JavaScript
  • Python
  • Rust
  • Go
  • Ruby
  • PHP / Composer
  • JVM
  • .NET / NuGet
EcossistemaManifesto obrigatórioLockfile / estado do projeto confiável
JavaScript / npmpackage.jsonpackage-lock.json ou npm-shrinkwrap.json; npm v1 legado bloqueado por padrão
JavaScript / pnpmpackage.jsonpnpm-lock.yaml
JavaScript / Yarnpackage.jsonyarn.lock
JavaScript / Bunpackage.jsonbun.lock
Pythonpyproject.toml, requirements*.txt, Pipfile, setup.cfg ou setup.pyo caminho confiável Poetry usa poetry.lock, o caminho confiável uv usa uv.lock, e pip-tools com hash completo é confiado apenas quando o grafo de requisitos commitado vincula exatamente os valores de --index-url e qualquer --extra-index-url; índices Python visíveis no repositório podem ser permitidos via trusted_indexes.pypi; modos Python confiáveis avaliam um perfil de instalação selecionado de cada vez (runtime por padrão, grupos/extras/platform/arch/version explícitos via CLI); manifestos legados permitidos com avisos por padrão
RustCargo.tomlCargo.lock
Gogo.modgo.sum obrigatório para deps externas
RubyGemfileGemfile.lock
PHP / Composercomposer.jsoncomposer.lock
JVM / Gradlebuild.gradle ou build.gradle.ktsgradle.lockfile
JVM / Mavenpom.xmlapenas aviso: nenhum caminho de lockfile local do projeto confiável ainda
.NET / NuGet.csproj

Fontes de configuração: caminho de arquivo local, URL HTTPS ou variável de ambiente SLOPPY_JOE_CONFIG. A configuração nunca é lida do diretório do projeto (veja CONFIG.md para o motivo).

Integração: use o modo de inicialização que corresponda ao repositório:

  • sloppy-joe init --greenfield --ecosystem <eco> imprime uma política inicial específica do ecossistema para novos projetos. Atualmente, predefinições greenfield são implementadas para npm, pypi e cargo; outros ecossistemas falham com um erro "ainda não suportado". Adicione --register para escrevê-la fora do repositório e registrá-la com segurança.
  • sloppy-joe init --from-current inspeciona o repositório atual e imprime sugestões de inicialização apenas para revisão. Atualmente, --from-current é implementado apenas para repositórios cujo código de primeira parte é npm e/ou cargo; outros ecossistemas falham fechados com um erro "ainda não implementado". Adicione --register para escrever e registrar a configuração gerada.
  • sloppy-joe init com nenhum modo imprime um modelo manual neutro.

Por que sloppy-joe?

Binário único. 8 ecossistemas. 16 tipos de ataque. Zero falsos positivos em verificações generativas. Configuração que agentes de IA não podem adulterar.

A maioria das ferramentas de segurança de dependências verifica uma ou duas coisas — existência ou distância de edição. sloppy-joe verifica 16 vetores de ataque em uma única passada: pacotes alucinados, 10 tipos de typosquatting (homóglifos, scope squatting, caracteres repetidos, confusão de separadores, reordenação de palavras, trocas adjacentes, caracteres omitidos, formas confusas, variantes de maiúsculas/minúsculas, sufixos de versão), aplicação canônica, bloqueio por idade de versão, amplificação de script de instalação, explosão de dependências, mudanças de mantenedor e vulnerabilidades conhecidas via OSV.dev.

Ele é executado como um único binário Rust sem dependências de tempo de execução. Ele suporta todos os 8 principais ecossistemas de pacotes. E sua configuração é projetada para segurança: nunca lida do diretório do projeto, carregável de uma URL para CI, com mensagens de erro claras quando algo está errado.

sloppy-joeSocket.devGuardDogPhantom Guardantislopsquat
Verificação de existência✅✅❌✅✅
Similaridade / typosquat✅✅✅✅❌
Detecção de homóglifos✅❌❌❌❌
Scope squatting✅❌❌❌❌
Aplicação canônica✅❌❌❌❌
Bloqueio por idade de versão✅❌❌❌❌
Amplificador de script de instalação✅✅❌❌❌
Explosão de dependências✅❌❌❌❌
Mudança de mantenedor✅✅❌❌❌
Verificação de vulnerabilidades OSV✅✅❌❌❌
Segurança de configuração (fora do repositório)✅N/A❌❌❌

🔶 = beta/experimental


Como Cada Ataque Funciona (e Como sloppy-joe o Bloqueia)

1. Pacotes alucinados

O ataque: IA gera import ai_json_helper. O pacote não existe. Um invasor registra ai-json-helper no PyPI com malware. Na próxima vez que alguém executar pip install, obterá o pacote malicioso.

Como sloppy-joe bloqueia: A verificação de existência consulta a API PyPI e obtém um 404. Build bloqueado.``` ERROR ai-json-helper [existence] Package 'ai-json-helper' does not exist on the pypi registry. It may be hallucinated by an AI code generator. Fix: Remove 'ai-json-helper' from your dependencies.

root@kitploit:~
### 2. Typosquatting (verificações generativas + fallback de distância de edição)

**O ataque:** Um invasor registra `expresz` no npm — um caractere diferente de `express`. A IA o gera, ou um desenvolvedor o digita errado. O pacote existe, passa na verificação de existência e instala malware.

**Como o sloppy-joe bloqueia:** o sloppy-joe executa 10 verificações generativas antes de recorrer à distância de edição. Cada verificação generativa produz uma mutação específica do nome da dependência (trocar caracteres, colapsar repetições, remover sufixos, reordenar palavras, normalizar separadores, substituir homóglifos, verificar escopos) e testa uma correspondência exata com pacotes populares conhecidos. Esta abordagem, inspirada na biblioteca [Typomania da Rust Foundation](https://github.com/rustfoundation/typomania), tem quase zero falsos positivos porque só dispara em correspondências exatas após a mutação.

A distância de edição de Levenshtein é executada por último como uma rede de segurança para mutações novas que nenhuma verificação específica antecipou. Juntos, eles cobrem tanto padrões de ataque conhecidos (precisamente) quanto desconhecidos (amplamente).```
ERROR expresz [similarity/edit-distance]
      'expresz' is 1 character away from 'express'. This could be a typosquat.
 Fix: If you meant 'express', fix the name in your manifest.

3. Caracteres repetidos

O ataque: expresss (s extra) ou reeact (e extra). Estes são padrões comuns de alucinação de IA — o modelo gera nomes com aparência plausível com caracteres repetidos.

Como sloppy-joe bloqueia isso: A verificação de caracteres repetidos reduz uma duplicata de cada vez e verifica se o resultado corresponde a um pacote conhecido. expresss → remove um s → express → corresponde.``` ERROR expresss [similarity/repeated-chars] 'expresss' matches 'express' after removing a repeated character. Fix: Use 'express' — remove the repeated characters.

root@kitploit:~
### 4. Confusão de separadores

**O ataque:** `python-dateutil` vs `python_dateutil` vs `pythondateutil`. Em alguns registros, esses são pacotes diferentes. Um invasor registra a variante.

**Como o sloppy-joe bloqueia isso:** Normaliza todos os separadores (`-`, `_`, `.`) antes da comparação. Se a forma normalizada corresponder a um pacote conhecido, ele é sinalizado.```
ERROR socket_io [similarity/separator-confusion]
      'socket_io' matches 'socket.io' after normalizing separators.
 Fix: Use the canonical name 'socket.io' with the correct separators.

5. Reordenação de palavras

O ataque: parse-json vs json-parse. A distância de Levenshtein é 8 — invisível para verificações de distância de edição. Mas um atacante pode registrar o nome reordenado.

Como o sloppy-joe bloqueia isso: Divide em separadores, gera todas as permutações dos segmentos e verifica cada uma contra o corpus. parse-json → permute → json-parse → match.``` ERROR parse-json [similarity/word-reorder] 'parse-json' is a reordering of 'json-parse'. Fix: Use 'json-parse' — the segments are in the wrong order.

root@kitploit:~
### 6. Trocas de caracteres adjacentes

**O ataque:** `reqeust` em vez de `request`. Dois caracteres adjacentes transpostos — um erro de digitação comum que atacantes exploram.

**Como o sloppy-joe bloqueia:** Gera todas as variantes de troca adjacente do nome da dependência e verifica cada uma em relação ao corpus.```
ERROR reqeusts [similarity/char-swap]
      'reqeusts' matches 'requests' with two adjacent characters swapped.
 Fix: Use 'requests' — two characters are transposed.

7. Caracteres omitidos

O ataque: reqests (faltando u) em vez de requests. A IA remove um caractere e o resultado é um nome com aparência válida.

Como sloppy-joe bloqueia: Insere cada caractere de a-z em cada posição no nome e verifica se algum resultado corresponde a um pacote conhecido. reqests + u na posição 3 → requests → correspondência.``` ERROR reqests [similarity/omitted-char] 'reqests' matches 'requests' with one character inserted. Fix: Use 'requests' — a character appears to be missing.

root@kitploit:~
### 8. Homoglifos (aparências visuais)

**O ataque:** `rеquests` com um `е` cirílico (U+0435) em vez do `e` latino (U+0065). Visualmente idênticos. O nome do pacote parece exatamente com `requests`, mas resolve para um pacote diferente e malicioso.

**Como o sloppy-joe bloqueia:** Substitui 17 caracteres homoglifos conhecidos (cirílico, largura total, variantes de script) por seus equivalentes latinos e verifica se o resultado corresponde a um pacote conhecido.```
ERROR rеquests [similarity/homoglyph]
      'rеquests' contains characters that look identical to 'requests'
      but are different Unicode codepoints (homoglyphs).
 Fix: Replace the lookalike characters with standard ASCII.

9. Formulários confusos de ecossistema

O ataque: py-utils vs python-utils. No PyPI, estes são pacotes diferentes. A IA gera um quando você queria o outro. Similarmente, github.com vs gitlab.com em módulos Go.

Como o sloppy-joe bloqueia: Aplica regras de substituição específicas do ecossistema (py↔python para PyPI, github↔gitlab para Go) e verifica se alguma variante corresponde a um pacote conhecido.``` ERROR py-flask [similarity/confused-form] 'py-flask' is a confused form of 'flask'. Fix: Use the canonical name 'flask'.

root@kitploit:~
### 10. Ataques de variação de maiúsculas/minúsculas (registros sensíveis a maiúsculas/minúsculas)

**O ataque:** No Go, Maven e Ruby, `Rails` e `rails` são pacotes diferentes. Um invasor registra a variante capitalizada.

**Como o sloppy-joe bloqueia:** Em registros sensíveis a maiúsculas/minúsculas, qualquer variação de maiúsculas/minúsculas de um pacote conhecido é sinalizada como erro. Em registros insensíveis a maiúsculas/minúsculas (npm, PyPI, Cargo, NuGet, PHP), as variações de maiúsculas/minúsculas são seguras e ignoradas.```
ERROR Rails [similarity/case-variant]
      'Rails' differs from 'rails' only in letter casing.
      On case-sensitive registries (ruby) these resolve to different packages.
 Fix: Use the exact casing 'rails' in your manifest.

11. Squatting de sufixo de versão

O ataque: requests2 ou lodash-4. A IA anexa um número de versão ao nome do pacote em vez de especificar a versão corretamente.

Como o sloppy-joe bloqueia isso: Remove dígitos e separadores finais e verifica se o nome base corresponde a um pacote conhecido.``` ERROR requests2 [similarity/version-suffix] 'requests2' looks like 'requests' with a version suffix appended. Fix: Use 'requests' and specify the version in your manifest's version field.

root@kitploit:~
### 12. Ataque de escopo (npm, PHP, Go, JVM)

**O ataque:** Um atacante registra `@typos/lodash` no npm — um caractere diferente de `@types/lodash`. Ou `larvael/framework` no Packagist — dois caracteres diferentes de `laravel/framework`. Ou `github.com/gooogle/protobuf` no Go — um `o` extra. O escopo parece legítimo à primeira vista. O pacote é resolvido. O malware é instalado.

Isso é raro, mas plausível — e "raro, mas plausível" é exatamente para o que sloppy-joe existe. O incidente com `ua-parser-js` em 2021 estava relacionado ao escopo. Se pode acontecer com um pacote com milhões de downloads semanais, pode acontecer com o seu.

**Como sloppy-joe bloqueia:** Extrai o escopo/namespace do nome da dependência e o compara com uma lista de escopos conhecidos como confiáveis usando distância de edição. Funciona em npm (`@scope`), PHP (`vendor/`), Go (`github.com/org`) e JVM (`com.group`).```
ERROR @typos/lodash [similarity/scope-squatting]
      Scope '@typos' is 1 character away from the known scope '@types'.
      Scope squatting is a known supply chain attack vector.
 Fix: If you meant '@types/lodash', fix the scope in your manifest.

[No content provided in the INPUT section. Please paste the Markdown chunk you wish to have translated.]``` ERROR github.com/gooogle/protobuf [similarity/scope-squatting] Scope 'github.com/gooogle' is 1 character away from 'github.com/google'. Fix: If you meant 'github.com/google/protobuf', fix the org name.

root@kitploit:~
### 13. Pacotes não canônicos (não é um ataque — uma barreira de consistência)

**O ataque:** Não é um ataque — um problema de consistência. IA escolhe `moment` porque era popular nos dados de treinamento, mas sua equipe usa `dayjs`. Diferentes equipes usando pacotes diferentes para a mesma tarefa cria dívida de manutenção e inchaço de dependências.

**Como o sloppy-joe bloqueia isso:** Seu config mapeia cada pacote canônico para suas alternativas rejeitadas. Se uma dependência corresponder a uma alternativa, a build falha.```
ERROR moment [canonical]
      'moment' is not the approved package for this purpose.
      Your team uses 'dayjs'.
 Fix: Replace 'moment' with 'dayjs' in your manifest file.

14. Versões muito novas (bomba-relógio da cadeia de suprimentos)

O ataque: Um atacante compromete a conta de um mantenedor de pacote (ou um mantenedor age de forma maliciosa) e publica uma versão de patch maliciosa. Parece uma atualização normal. Se seu CI a instalar imediatamente, você estará comprometido antes que alguém perceba.

Como o sloppy-joe bloqueia: O gate de idade da versão bloqueia qualquer dependência cuja versão foi publicada há menos de min_version_age_hours horas (padrão: 72 horas). Isso dá tempo para a comunidade, Socket.dev e outros scanners sinalizarem versões maliciosas.``` ERROR react [metadata/version-age] Version '^19.0.0' of 'react' was published 6 hours ago (minimum: 72 hours). New versions need time for the community and security scanners to review them. Fix: Wait until the version is at least 72 hours old, or pin to an older version.

root@kitploit:~
### 15. Pacotes Novos

**O ataque:** Um pacote criado ontem com 3 downloads que tem um nome semelhante a um pacote popular. Alta probabilidade de ser um typosquat ou um placeholder para um ataque futuro.

**Como o sloppy-joe bloqueia:** Sinaliza qualquer pacote criado há menos de 30 dias.```
ERROR sketchy-lib [metadata/new-package]
      'sketchy-lib' was first published 2 days ago.
      New packages are higher risk.
 Fix: Verify 'sketchy-lib' at its registry page and source repository.

16. Pacotes com poucos downloads

O ataque: Um pacote com 12 downloads que está a um caractere de distância de requests. Quase certamente um typosquat.

Como o sloppy-joe bloqueia: Sinaliza pacotes com menos de 100 downloads (onde o registro fornece dados de download — atualmente npm, crates.io, RubyGems).``` ERROR requsets [metadata/low-downloads] 'requsets' has only 12 downloads. Fix: Verify 'requsets' is the package you intend to use.

root@kitploit:~
---

## Ecossistemas Suportados

| Ecossistema | Manifesto | Política de Lockfile | Existência | Metadados | Validação de Idade |
|-----------|----------|-----------------|:---------:|:--------:|:--------:|
| npm | package.json | `package-lock.json` ou `npm-shrinkwrap.json` obrigatório | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| PyPI | `pyproject.toml`, `requirements*.txt`, `Pipfile`, `setup.cfg`, `setup.py` | Poetry é confiável com `poetry.lock`, uv é confiável com `uv.lock`, pip-tools totalmente bloqueado por hash é confiável apenas quando o grafo de requisitos commitado vincula `--index-url` e valores exatos de `--extra-index-url` na lista de permissões, e índices personalizados do Poetry/uv visíveis no repositório podem ser confiáveis apenas pela lista de permissões exata `trusted_indexes.pypi`; manifestos legados emitem aviso a cada execução a menos que `python_enforcement` seja `poetry_only` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Cargo | Cargo.toml | `Cargo.lock` obrigatório | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Go | go.mod | `go.sum` obrigatório para dependências externas; não obrigatório para stdlib-only ou `replace` totalmente local | :white_check_mark: | :x: | :x: |
| Ruby | Gemfile | `Gemfile.lock` obrigatório | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| PHP | composer.json | `composer.lock` obrigatório | :white_check_mark: | :x: | :x: |
| JVM (Gradle) | build.gradle / build.gradle.kts | `gradle.lockfile` obrigatório | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| JVM (Maven) | pom.xml | apenas aviso: sem imposição rigorosa de lockfile | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| .NET | *.csproj | `packages.lock.json` obrigatório | :white_check_mark: | :x: | :x: |

Todos os ecossistemas recebem verificações de existência + similaridade + canônicas. Metadados e validação de idade dependem do que a API do registro expõe. O suporte a lockfile permite a varredura de dependências transitivas e a resolução exata de versões onde o ecossistema fornece um modelo de lockfile local confiável ao projeto.

## Início Rápido```bash
# Install
cargo install sloppy-joe

# Check current project (auto-detects ecosystem)
sloppy-joe check

# Check with canonical enforcement and age gate
sloppy-joe check --config /etc/sloppy-joe/config.json

# Output as JSON for CI
sloppy-joe check --json

Códigos de Saída

CódigoSignificado
0Todas as verificações passaram
1Problemas encontrados
2Erro em tempo de execução

Config```json

{ "canonical": { "npm": { "lodash": ["underscore", "ramda", "lazy.js"], "dayjs": ["moment", "luxon"], "axios": ["request", "got", "node-fetch", "superagent"] }, "pypi": { "httpx": ["urllib3", "requests"], "ruff": ["flake8", "pylint"] } }, "internal": { "go": ["github.com/yourorg/"], "npm": ["@yourorg/"] }, "allowed": { "npm": ["some-vetted-external-pkg"] }, "similarity_exceptions": { "cargo": [ { "package": "serde_json", "candidate": "serde", "generator": "segment-overlap" } ] }, "metadata_exceptions": { "cargo": [ { "package": "colored", "check": "metadata/maintainer-change", "version": "2.2.0", "previous_publisher": "kurtlawrence", "current_publisher": "hwittenborn" } ] }, "min_version_age_hours": 72, "allow_legacy_npm_v1_lockfile": false, "python_enforcement": "prefer_poetry" }

root@kitploit:~
**`canonical`** — as chaves são pacotes aprovados; os valores são alternativas rejeitadas.

**`internal`** — os pacotes da sua organização. Pule TODAS as verificações. Eles mudam constantemente.

**`allowed`** — pacotes externos verificados. Pule existência + similaridade, mas ainda sujeito ao limite de idade da versão.

**`similarity_exceptions`** — supressões exatas de pacote/candidato/gerador para falsos positivos de similaridade revisados. Use isso quando uma aresta de similaridade específica estiver errada, mas você ainda quer verificações normais no pacote.

**`metadata_exceptions`** — supressões exatas de metadados revisados. Atualmente, isso só suporta `metadata/maintainer-change`, e requer uma correspondência exata de pacote/versão/publicador-anterior/publicador-atual.

Use `sloppy-joe check --review-exceptions` quando você precisa revisar os bloqueadores de mudança de mantenedor. A varredura ainda bloqueia normalmente, mas a saída legível adiciona uma seção `REVIEW EXCEPTIONS` com proprietários, URL do repositório e um trecho `metadata_exceptions` pronto para colar. `--json` inclui os mesmos dados em um campo `review_candidates` de nível superior.

**`min_version_age_hours`** — bloqueie qualquer versão publicada há menos de N horas. Padrão: 72 (3 dias). Defina como 0 para desabilitar. Pacotes internos são isentos.

**`allow_legacy_npm_v1_lockfile`** — permitir lockfiles npm `lockfileVersion: 1` do npm v5/v6 em modo de confiança reduzida. Padrão: `false`. Mantenha desligado, a menos que você esteja intencionalmente preso ao npm legado e aceite avisos altos e cobertura reduzida de confiança de dependências transitivas npm.

**`python_enforcement`** — controla a política de confiança do Python. `prefer_poetry` (padrão) confia em projetos Poetry e uv, confia em requisitos pip-tools totalmente bloqueados por hash apenas quando o grafo de requisitos commitado vincula explicitamente `--index-url` e quaisquer valores não-PyPI de `--extra-index-url`, e caso contrário rebaixa pip-tools para confiança reduzida. Manifestos legados como `requirements*.txt` sem hash, `Pipfile`, `setup.cfg`, `setup.py` e `pyproject.toml` não-Poetry/não-uv avisam a cada execução. `poetry_only` bloqueia esses workflows Python não-Poetry e exige Poetry.

### Segurança da Configuração

A configuração **nunca é lida do diretório do projeto**. Um agente de IA com acesso ao shell poderia reescrever uma configuração no repositório para permitir o que quisesse.

Resolução da configuração:
1. `--config /path/to/config.json` — arquivo local (flag CLI, prioridade mais alta)
2. `--config https://example.com/config.json` — buscar da URL
3. `SLOPPY_JOE_CONFIG=...` — variável de ambiente (caminho de arquivo ou URL)
4. Sem configuração = apenas verificações de existência + similaridade + metadados

Configurações malformadas **falham fortemente** com mensagens de erro acionáveis — uma configuração quebrada nunca retorna silenciosamente para nenhuma proteção.

Veja [CONFIG.md](https://github.com/brennhill/sloppy-joe/blob/main/CONFIG.md) para referência completa de formato, padrões de integração CI e exemplos.

Configuração de inicialização:```bash
sloppy-joe init --greenfield --ecosystem npm
sloppy-joe init --from-current
sloppy-joe init --from-current --register
sloppy-joe init --register

Integração CI

GitHub Actions

A maneira mais rápida de adicionar sloppy-joe ao seu pipeline de CI — baixa um binário pré-compilado do GitHub Releases (sem necessidade de toolchain Rust):```yaml

.github/workflows/deps.yml

name: Dependency Check on: [push, pull_request]

jobs: sloppy-joe: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: brennhill/[email protected] with: config: https://raw.githubusercontent.com/yourorg/configs/main/sloppy-joe.json

root@kitploit:~
#### Entradas da Ação

| Input | Descrição | Padrão |
|-------|-----------|--------|
| `config` | Caminho do arquivo de configuração ou URL HTTPS | *(nenhum)* |
| `dir` | Diretório do projeto a ser escaneado | `.` |
| `type` | Ecossistema (`npm`, `pypi`, `cargo`, `go`, `ruby`, `php`, `jvm`, `dotnet`) | auto-detect |
| `deep` | Ativar verificações de similaridade de dependências transitivas | `false` |
| `paranoid` | Ativar mutações de bitflip | `false` |
| `args` | Argumentos adicionais de CLI | *(nenhum)* |
| `version` | versão do sloppy-joe a ser instalada | `latest` |

#### Exemplos```yaml
# Minimal — CI-oriented scan, auto-detect ecosystem, no config
- uses: brennhill/[email protected]

# With org config from a URL
- uses: brennhill/[email protected]
  with:
    config: https://raw.githubusercontent.com/yourorg/configs/main/sloppy-joe.json

# Deep scan with paranoid mode
- uses: brennhill/[email protected]
  with:
    config: ${{ secrets.SLOPPY_JOE_CONFIG }}
    deep: true
    paranoid: true

# Scan a subdirectory, pin to a specific version
- uses: brennhill/[email protected]
  with:
    dir: ./packages/api
    version: '1.1.0'

GitLab CI```yaml

dependency-guard: script: - cargo install sloppy-joe - sloppy-joe check --ci --config $SLOPPY_JOE_CONFIG

root@kitploit:~
### pre-commit

sloppy-joe funciona com o framework [pre-commit](https://pre-commit.com).
Adicione-o ao seu `.pre-commit-config.yaml`:```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/brennhill/sloppy-joe
    rev: v1.1.0
    hooks:
      - id: sloppy-joe

O hook executa sloppy-joe check em cada commit (e opcionalmente no push). Ele detecta automaticamente seu ecossistema a partir dos arquivos de manifesto. Passe argumentos adicionais via args:```yaml - id: sloppy-joe args: [--config, "https://example.com/config.json"]

root@kitploit:~
Ou use um simples shell hook sem o framework:```bash
#!/bin/sh
sloppy-joe check || exit 1

Arquitetura

sloppy-joe usa uma abordagem generativa baseada em registro para detecção de similaridade. Em vez de comparar cada dependência com um corpus estático usando distância de edição (que produz falsos positivos), ela gera mutações específicas de cada nome de dependência, consulta o registro para verificar se a mutação existe e sinaliza correspondências exatas.``` Pipeline (in order):

  1. Canonical check — flag deps that violate org standards
  2. Similarity check — 8 mutation generators + scope squatting
  3. Metadata check — version age, new package, downloads, install scripts, dep explosion, maintainer change
  4. Existence check — flag packages that don't exist on the registry
  5. Malicious check — query OSV.dev for known vulnerabilities
root@kitploit:~
Similaridade executa 4 fases:
- **Fase 0: Scope squatting** — verificação local, sem rede. Compara escopo/namespace com escopos conhecidos como seguros via distância de Levenshtein.
- **Fase 1: Intra-manifesto** — verificação local. Sinaliza quando duas dependências no mesmo manifesto são mutações uma da outra.
- **Fase 2: Consulta ao registro** — gera mutações, consulta o registro em lote para verificar existência, armazena resultados em cache (TTL de 7 dias).
- **Fase 3: Enriquecimento de metadados** — busca contagens de downloads e datas de publicação para correspondências, adicionando evidências aos relatórios.

Cada gerador de mutação marca sua saída, de modo que o tipo de verificação reportado (por exemplo, `similarity/homoglyph`) é determinístico — o gerador de maior severidade vence quando múltiplos geradores produzem o mesmo candidato.

## Confiabilidade CI

sloppy-joe é projetado para pipelines de CI onde falhas instáveis são inaceitáveis.

**Repetição com backoff.** Todas as chamadas HTTP do registro são repetidas 3 vezes com backoff exponencial (200ms, 400ms, 800ms) em falhas transitórias (5xx, timeouts, erros de conexão). Um único pico de rede não falhará sua build.

**Falha fechada em erros de consulta.** Se as consultas ao registro ou OSV falharem, sloppy-joe emite um erro bloqueante `registry-unreachable` em vez de pular verificações silenciosamente. A varredura não depende mais de limites por ecossistema ou cortes de tamanho de amostra antes de bloquear.

**Cache de similaridade.** Resultados de existência de mutação são armazenados em cache por 7 dias. Após a primeira varredura, a maioria das consultas é servida a partir do cache, sem chamadas de rede. Apenas dependências novas acionam consultas ao registro.

**Resolução ciente de lockfile.** Quando um lockfile suportado está presente e confiável (`package-lock.json`, `npm-shrinkwrap.json`, `Cargo.lock`, `Gemfile.lock`, `poetry.lock` para projetos Poetry, `uv.lock` para projetos uv, `composer.lock`, `gradle.lockfile`, `packages.lock.json`), sloppy-joe resolve versões exatas a partir dele em vez de adivinhar a partir de intervalos. Arquivos `requirements*.txt` totalmente bloqueados por hash também podem fornecer versões exatas fixadas, e eles se tornam totalmente confiáveis quando o grafo de requisitos versionado vincula seu próprio `--index-url` e valores de `--extra-index-url` explicitamente na lista de permissões.

## Testes

O conjunto de testes cobre verificações de similaridade, sinais de metadados, comportamento OSV, análise e validação de configuração, resolução de lockfile, política de pré-verificação de manifesto e lockfile, formatação de relatório e lógica de repetição HTTP.```bash
cargo test

Construído sobre

  • Typomania — Biblioteca de typosquatting da Rust Foundation, que inspirou a abordagem de mutação generativa (o sloppy-joe implementa seus próprios geradores em vez de usar a crate diretamente)
  • strsim — Distância de Levenshtein, usada para detecção de scope squatting
  • reqwest — Cliente HTTP assíncrono com retry para consultas ao registro
  • OSV.dev — Base de dados de vulnerabilidades conhecidas para detecção de pacotes maliciosos

Como o sloppy-joe se compara

Funcionalidadesloppy-joeSocket.devcargo-denypip-auditnpm audit
Detecção de pacotes alucinados✅❌❌❌❌
Detecção de typosquatting✅ 11 geradoresParcial❌❌❌
Imposição de nomes canônicos✅❌❌❌❌
Varredura de vulnerabilidades conhecidas✅ via OSV✅✅✅✅
Análise de scripts de instalaçãoBásico (flag + sem repositório)✅ Análise aprofundada❌❌❌
Conformidade de licençaFora de escopo: conformidade, não segurança✅✅ ExcelenteFora de escopo: conformidade, não segurançaFora de escopo: conformidade, não segurança
Multi-ecossistema8 ecossistemasnpm, PyPI, Go, Ruby, Java, .NETApenas RustApenas PythonApenas npm
Segurança de agente IA (configuração fora do repositório)✅❌❌❌❌
Amigável para offline/CI✅ Funciona em qualquer lugarRequer plataforma Socket✅✅✅
Gratuito / código abertoApache 2.0Camada gratuita + paga

Onde os outros são mais fortes: Socket.dev faz análise aprofundada de scripts de instalação com detecção comportamental que vai muito além da abordagem baseada em flags do sloppy-joe. cargo-deny possui verificação de conformidade de licença de melhor qualidade, mas isso está intencionalmente fora do escopo do sloppy-joe porque a política de licenças é um problema de conformidade, e não um controle de segurança de dependências. npm audit e pip-audit são opções de instalação zero para varredura de vulnerabilidades em ecossistemas únicos.

Onde o sloppy-joe é diferente: É a única ferramenta que verifica se os pacotes realmente existem nos registros (capturando alucinações de IA), executa 11 geradores de typosquatting com quase zero falsos positivos, impõe escolhas de pacotes canônicos e mantém sua configuração fora do repositório para que os agentes de IA não possam enfraquecer suas próprias verificações.

Licença

Apache 2.0

Baixar ferramenta
packages.lock.json
Listas internas + permitidas✅❌❌❌❌
npm✅✅✅✅❌
PyPI✅✅✅✅✅
Cargo✅✅❌✅❌
Go✅✅✅❌❌
Ruby✅✅✅❌❌
PHP✅🔶❌❌❌
JVM (Gradle/Maven)✅✅❌❌❌
.NET (NuGet)✅✅❌❌❌
Binário único✅❌❌❌❌
Código abertoApache 2.0ComercialApache 2.0MITOSS
LinguagemRustSaaSPythonPythonPython
Apache 2.0
Apache 2.0
Integrado