Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
sloppy-joe — Protegge dagli attacchi alla supply chain, slopsquatting e typosquatting provenienti da dipendenze e codice. | Kitploit
Strumenti/GitHubGitHub/brennhill/sloppy-joe
Analisi StaticaScanner di VulnerabilitàAnalisi del CodiceDevSecOpsRilevamento SegretiThreat IntelligenceSicurezza della Supply ChainApprendimento e Formazione
GitHubbrennhill/sloppy-joe

sloppy-joe

Protegge dagli attacchi alla supply chain, slopsquatting e typosquatting provenienti da dipendenze e codice.

Vedi Repository
3214 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

sloppy-joe

Individua dipendenze allucinate, typosquatted e non canoniche
prima che arrivino in produzione.

cargo install sloppy-joe


L'attacco alla supply chain di LiteLLM (marzo 2026) ha compromesso un pacchetto con 97 milioni di download mensili. Gli attaccanti hanno rubato le credenziali di pubblicazione e hanno spinto versioni malevole che hanno raccolto chiavi SSH, credenziali cloud e segreti K8s. La soglia di età predefinita di 72 ore di sloppy-joe avrebbe bloccato entrambe le versioni avvelenate: sono state scoperte in poche ore, ben prima che la soglia si aprisse. Se esegui sloppy-joe check in CI, questo attacco fallisce. Analisi completa

I generatori di codice AI allucinano i nomi dei pacchetti circa il 20% delle volte. Gli attaccanti registrano quei nomi e aspettano. sloppy-joe li intercetta in CI prima che vengano eseguiti npm install o pip install.

Come Usare```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

Modalità di scansione:

  • sloppy-joe check esegue il guardrail locale veloce. Impone sempre l'analisi del manifest, il lockfile/sync, la provenienza e la politica sulle sorgenti non supportate. Se lo stato delle dipendenze o della politica è cambiato, o se l'ultima scansione completa con successo è più vecchia di 24 ore, consiglia sloppy-joe check --full.
  • sloppy-joe check --full esegue la scansione online rigorosa e aggiorna lo stato registrato dell'ultima scansione completa con successo.
  • sloppy-joe check --ci esegue la stessa copertura rigorosa di --full, con finalità CI.
  • Per Python, sloppy-joe check valuta il profilo runtime per impostazione predefinita. Se esistono dipendenze con ambito, avvisa e dice di passare flag espliciti --python-groups, --python-extras, --python-platform e/o --python-version per la parità CI/build.
  • L'output leggibile in chiaro di sloppy-joe check ricorda sempre di usare o per CI e gating di produzione.

Codici di uscita: 0 = nessun problema bloccante trovato nella modalità selezionata, 1 = problemi bloccanti trovati, 2 = errore runtime.

Supporta: JavaScript (npm, pnpm, Yarn, Bun), Python, Rust, Go, Ruby, PHP, JVM (Gradle/Maven) e .NET — rilevati automaticamente dai file manifest.

Guide per ecosistemi: consulta docs/ecosystems/README.md per il modello di fiducia corrente, le funzionalità supportate e i limiti di fail-closed per ogni ecosistema.

  • JavaScript
  • Python
  • Rust
  • Go
  • Ruby
  • PHP / Composer
  • JVM
  • .NET / NuGet

Fonti di configurazione: percorso file locale, URL HTTPS o variabile d'ambiente SLOPPY_JOE_CONFIG. La configurazione non viene mai letta dalla directory del progetto (vedi CONFIG.md per il motivo).

Onboarding: usa la modalità bootstrap che corrisponde al repository:

  • sloppy-joe init --greenfield --ecosystem <eco> stampa una politica iniziale specifica per l'ecosistema per nuovi progetti. Oggi, i preset greenfield sono implementati per npm, pypi e cargo; altri ecosistemi falliscono con un errore “not supported yet”. Aggiungi --register per scriverla fuori dal repository e registrarla in modo sicuro.
  • sloppy-joe init --from-current ispeziona il repository corrente e stampa suggerimenti bootstrap solo per revisione. Oggi, --from-current è implementato solo per repository il cui codice di prima parte è npm e/o cargo; altri ecosistemi falliscono chiusi con un errore “not implemented yet”. Aggiungi --register per scrivere e registrare la configurazione generata.
  • sloppy-joe init senza modalità stampa un template manuale neutro.

Perché sloppy-joe?

Singolo binario. 8 ecosistemi. 16 tipi di attacco. Zero falsi positivi sui controlli generativi. Configurazione che gli agenti AI non possono manomettere.

La maggior parte degli strumenti di sicurezza delle dipendenze controlla una o due cose — esistenza o distanza di modifica. sloppy-joe controlla 16 vettori d'attacco in un unico passaggio: pacchetti allucinati, 10 tipi di typosquatting (omoglifi, scope squatting, caratteri ripetuti, confusione di separatori, riordino di parole, scambi adiacenti, caratteri omessi, forme confuse, varianti di caso, suffissi di versione), enforcement canonico, gating per età della versione, amplificazione dello script di installazione, esplosione di dipendenze, cambiamenti di manutentore e vulnerabilità note tramite OSV.dev.

Viene eseguito come singolo binario Rust senza dipendenze runtime. Supporta tutti gli 8 principali ecosistemi di pacchetti. E la sua configurazione è progettata per la sicurezza: mai letta dalla directory del progetto, caricabile da un URL per CI, con messaggi di errore chiari quando qualcosa non va.

🔶 = beta/sperimentale


Come Funziona Ogni Attacco (e Come sloppy-joe lo Blocca)

1. Pacchetti allucinati

L'attacco: L'IA genera import ai_json_helper. Il pacchetto non esiste. Un attaccante registra ai-json-helper su PyPI con malware. La prossima volta che qualcuno esegue pip install, ottiene il pacchetto malevolo.

Come sloppy-joe lo blocca: Il controllo di esistenza interroga l'API PyPI e ottiene un 404. Build bloccata.``` 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 (controlli generativi + fallback basato sulla distanza di edit)

**L'attacco:** Un utente malintenzionato registra `expresz` su npm — un carattere diverso da `express`. L'IA lo genera, o uno sviluppatore lo scrive a tastiera. Il pacchetto esiste, supera il controllo di esistenza e installa malware.

**Come sloppy-joe lo blocca:** sloppy-joe esegue 10 controlli generativi prima di ricorrere alla distanza di edit. Ogni controllo generativo produce una mutazione specifica del nome della dipendenza (scambia caratteri, comprime ripetizioni, rimuovi suffissi, riordina parole, normalizza separatori, sostituisci omoglifi, controlla gli scope) e testa una corrispondenza esatta con pacchetti popolari noti. Questo approccio, ispirato alla libreria [Typomania della Rust Foundation](https://github.com/rustfoundation/typomania), ha falsi positivi quasi nulli perché si attiva solo su corrispondenze esatte dopo la mutazione.

La distanza di edit di Levenshtein viene eseguita per ultima come rete di sicurezza per mutazioni inedite che nessun controllo specifico aveva previsto. Insieme, coprono sia schemi di attacco noti (con precisione) sia quelli sconosciuti (in modo ampio).```
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. Caratteri ripetuti

L'attacco: expresss (s in più) o reeact (e in più). Questi sono comuni schemi di allucinazione dell'IA — il modello genera nomi dall'aspetto plausibile con caratteri ripetuti.

Come sloppy-joe lo blocca: Il controllo dei caratteri ripetuti collassa un duplicato alla volta e verifica se il risultato corrisponde a un pacchetto noto. expresss → rimuovi una s → express → corrispondenza.``` ERROR expresss [similarity/repeated-chars] 'expresss' matches 'express' after removing a repeated character. Fix: Use 'express' — remove the repeated characters.

root@kitploit:~
### 4. Confusione dei separatori

**L'attacco:** `python-dateutil` vs `python_dateutil` vs `pythondateutil`. In alcuni registri, questi sono pacchetti diversi. Un attaccante registra la variante.

**Come sloppy-joe lo blocca:** Normalizza tutti i separatori (`-`, `_`, `.`) prima del confronto. Se la forma normalizzata corrisponde a un pacchetto noto, viene segnalato.```
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. Riordinamento delle parole

L'attacco: parse-json vs json-parse. La distanza di Levenshtein è 8 — invisibile ai controlli basati sulla distanza di modifica. Ma un utente malintenzionato può registrare il nome riordinato.

Come sloppy-joe lo blocca: Suddivide in base ai separatori, genera tutte le permutazioni dei segmenti e verifica ciascuna rispetto al corpus. parse-json → permuta → json-parse → corrispondenza.``` 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. Scambi di caratteri adiacenti

**L'attacco:** `reqeust` invece di `request`. Due caratteri adiacenti trasposti — un errore di battitura comune che gli attaccanti sfruttano.

**Come sloppy-joe lo blocca:** Genera tutte le varianti di scambio adiacente del nome della dipendenza e controlla ciascuna rispetto al corpus.```
ERROR reqeusts [similarity/char-swap]
      'reqeusts' matches 'requests' with two adjacent characters swapped.
 Fix: Use 'requests' — two characters are transposed.

7. Caratteri omessi

L'attacco: reqests (mancante u) invece di requests. L'AI omette un carattere e il risultato è un nome dall'aspetto valido.

Come sloppy-joe lo blocca: Inserisce ogni carattere a-z in ogni posizione del nome e controlla se qualche risultato corrisponde a un pacchetto noto. reqests + u alla posizione 3 → requests → corrispondenza.``` ERROR reqests [similarity/omitted-char] 'reqests' matches 'requests' with one character inserted. Fix: Use 'requests' — a character appears to be missing.

root@kitploit:~
### 8. Omoglifi (somiglianze visive)

**L'attacco:** `rеquests` con una `е` cirillica (U+0435) invece della `e` latina (U+0065). Visivamente identico. Il nome del pacchetto sembra esattamente `requests` ma risolve in un pacchetto diverso e malevolo.

**Come sloppy-joe lo blocca:** Sostituisce 17 caratteri omoglifi noti (cirillici, a larghezza intera, varianti script) con i loro equivalenti latini e controlla se il risultato corrisponde a un pacchetto noto.```
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. Forme confuse dell'ecosistema

L'attacco: py-utils vs python-utils. Su PyPI, questi sono pacchetti diversi. L'AI genera uno quando intendevi l'altro. Allo stesso modo, github.com vs gitlab.com nei moduli Go.

Come sloppy-joe lo blocca: Applica regole di sostituzione specifiche dell'ecosistema (py↔python per PyPI, github↔gitlab per Go) e verifica se una qualsiasi variante corrisponde a un pacchetto noto.``` ERROR py-flask [similarity/confused-form] 'py-flask' is a confused form of 'flask'. Fix: Use the canonical name 'flask'.

root@kitploit:~
### 10. Attacchi con varianti di maiuscole/minuscole (registry case-sensitive)

**L'attacco:** Su Go, Maven e Ruby, `Rails` e `rails` sono pacchetti diversi. Un attaccante registra la variante con iniziale maiuscola.

**Come sloppy-joe lo blocca:** Nei registry case-sensitive, qualsiasi variante di maiuscole/minuscole di un pacchetto noto viene segnalata come errore. Nei registry case-insensitive (npm, PyPI, Cargo, NuGet, PHP), le varianti di maiuscole/minuscole sono sicure e vengono saltate.```
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. Attacco tramite suffisso di versione

L'attacco: requests2 o lodash-4. L'IA aggiunge un numero di versione al nome del pacchetto invece di specificare la versione correttamente.

Come sloppy-joe lo blocca: Rimuove le cifre e i separatori finali e verifica se il nome base corrisponde a un pacchetto noto.``` 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. Scope squatting (npm, PHP, Go, JVM)

**L'attacco:** Un attaccante registra `@typos/lodash` su npm — un carattere di differenza da `@types/lodash`. Oppure `larvael/framework` su Packagist — due caratteri di differenza da `laravel/framework`. Oppure `github.com/gooogle/protobuf` su Go — una `o` in più. Lo scope sembra legittimo a prima vista. Il pacchetto viene risolto. Il malware si installa.

È raro ma plausibile — e "raro ma plausibile" è esattamente ciò per cui esiste sloppy-joe. L'incidente `ua-parser-js` del 2021 era legato allo scope. Se può accadere a un pacchetto con milioni di download settimanali, può accadere al vostro.

**Come sloppy-joe lo blocca:** Estrae lo scope/namespace dal nome della dipendenza e lo confronta con un elenco di scope noti come affidabili utilizzando la distanza di modifica. Funziona su 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.

Licenza

yush è fatto con ♥ da @thehappydinoa e rilasciato sotto la licenza MIT.

root@kitploit:~
© 2021 Aidan Holland```

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. Pacchetti non canonici (non è un attacco — un gate di coerenza)

**L'attacco:** Non è un attacco — un problema di coerenza. L'IA sceglie `moment` perché era popolare nei dati di addestramento, ma il tuo team usa `dayjs`. Team diversi che usano pacchetti diversi per lo stesso compito creano debito di manutenzione e gonfiore delle dipendenze.

**Come sloppy-joe lo blocca:** La tua configurazione mappa ogni pacchetto canonico alle sue alternative rifiutate. Se una dipendenza corrisponde a un'alternativa, la build fallisce.```
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. Versioni troppo recenti (bomba a orologeria nella supply chain)

L'attacco: Un attaccante compromette l'account di un manutentore (oppure un manutentore si ribella) e pubblica una versione patch dannosa. Sembra un aggiornamento normale. Se la tua CI lo installa immediatamente, sei compromesso prima che qualcuno se ne accorga.

Come sloppy-joe lo blocca: Il gate dell'età della versione blocca qualsiasi dipendenza la cui versione è stata pubblicata meno di min_version_age_hours ore fa (default: 72 ore). Questo dà il tempo alla community, a Socket.dev e ad altri scanner di segnalare le versioni dannose.``` 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. Pacchetti nuovissimi

**L'attacco:** Un pacchetto creato ieri con 3 download che ha un nome simile a un pacchetto popolare. Alta probabilità che si tratti di un typosquat o di un segnaposto per un futuro attacco.

**Come sloppy-joe lo blocca:** Segnala qualsiasi pacchetto creato meno di 30 giorni fa.```
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. Pacchetti con pochi download

L'attacco: Un pacchetto con 12 download che si trova a un solo carattere di distanza da requests. Quasi certamente un typosquatting.

Come sloppy-joe lo blocca: Segnala i pacchetti con meno di 100 download (laddove il registro fornisce dati sui download — attualmente 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:~
---

## Ecosistemi Supportati

| Ecosistema | Manifesto | Politica del Lockfile | Esistenza | Metadati | Controllo Età |
|-----------|----------|-----------------|:---------:|:--------:|:--------:|
| npm | package.json | `package-lock.json` o `npm-shrinkwrap.json` richiesto | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| PyPI | `pyproject.toml`, `requirements*.txt`, `Pipfile`, `setup.cfg`, `setup.py` | Poetry è considerato affidabile con `poetry.lock`, uv è considerato affidabile con `uv.lock`, pip-tools con hash completamente bloccato è considerato affidabile solo quando il grafo delle dipendenze committato vincola `--index-url` e valori esatti di `--extra-index-url` nella allowlist, e gli indici personalizzati di Poetry/uv visibili nel repository possono essere considerati affidabili solo tramite la allowlist esatta di `trusted_indexes.pypi`; i manifesti legacy avvisano a ogni esecuzione a meno che `python_enforcement` non sia `poetry_only` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Cargo | Cargo.toml | `Cargo.lock` richiesto | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Go | go.mod | `go.sum` richiesto per dipendenze esterne; non richiesto per solo stdlib o per tutti i `replace` locali | :white_check_mark: | :x: | :x: |
| Ruby | Gemfile | `Gemfile.lock` richiesto | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| PHP | composer.json | `composer.lock` richiesto | :white_check_mark: | :x: | :x: |
| JVM (Gradle) | build.gradle / build.gradle.kts | `gradle.lockfile` richiesto | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| JVM (Maven) | pom.xml | solo avviso: nessuna applicazione rigorosa del lockfile | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| .NET | *.csproj | `packages.lock.json` richiesto | :white_check_mark: | :x: | :x: |

Tutti gli ecosistemi ricevono controlli di esistenza, similarità e canonicità. I metadati e il controllo età dipendono da ciò che espone l'API del registro. Il supporto al lockfile abilita la scansione delle dipendenze transitive e la risoluzione esatta delle versioni dove l'ecosistema fornisce un modello di lockfile locale al progetto attendibile.

## Avvio Rapido```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

Codici di Uscita

CodiceSignificato
0Tutti i controlli superati
1Problemi trovati
2Errore di runtime

Configurazione```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`** — le chiavi sono pacchetti approvati; i valori sono alternative rifiutate.

**`internal`** — i pacchetti della tua organizzazione. Salta TUTTI i controlli. Questi cambiano costantemente.

**`allowed`** — pacchetti esterni verificati. Salta esistenza + similarità, ma ancora soggetti al gate dell'età della versione.

**`similarity_exceptions`** — soppressioni esatte di pacchetto/candidato/generatore per falsi positivi di similarità revisionati. Usa questo quando uno specifico bordo di similarità è sbagliato ma desideri comunque i controlli normali sul pacchetto.

**`metadata_exceptions`** — soppressioni esatte di metadati revisionati. Attualmente questo supporta solo `metadata/maintainer-change`, e richiede una corrispondenza esatta di pacchetto/versione/editore-precedente/editore-attuale.

Usa `sloppy-joe check --review-exceptions` quando hai bisogno di revisionare i blocchi per cambiamento del manutentore. La scansione blocca ancora normalmente, ma l'output umano aggiunge una sezione `REVIEW EXCEPTIONS` con proprietari, URL del repository e un frammento `metadata_exceptions` pronto da incollare. `--json` include gli stessi dati in un campo `review_candidates` di primo livello.

**`min_version_age_hours`** — blocca qualsiasi versione pubblicata meno di questo numero di ore fa. Default: 72 (3 giorni). Imposta a 0 per disabilitare. I pacchetti interni sono esenti.

**`allow_legacy_npm_v1_lockfile`** — consenti i lockfile npm `lockfileVersion: 1` da npm v5/v6 in modalità fiducia ridotta. Default: `false`. Tienilo disattivato a meno che tu non sia intenzionalmente bloccato su npm legacy e accetti avvisi rumorosi più una copertura di fiducia ridotta delle dipendenze transitive npm.

**`python_enforcement`** — controlla la politica di fiducia per Python. `prefer_poetry` (default) si fida dei progetti Poetry e uv, si fida dei requisiti pip-tools completamente bloccati da hash solo quando il grafico dei requisiti committato lega esattamente `--index-url` e qualsiasi valore `--extra-index-url` non PyPI, e altrimenti declassa pip-tools a fiducia ridotta. I manifest legacy come `requirements*.txt` senza hash, `Pipfile`, `setup.cfg`, `setup.py` e `pyproject.toml` non Poetry/non uv avvertono a ogni esecuzione. `poetry_only` blocca quei flussi di lavoro Python non Poetry e richiede Poetry.

### Sicurezza della Configurazione

La configurazione **non viene mai letta dalla directory del progetto**. Un agente AI con accesso shell potrebbe riscrivere una configurazione nel repository per inserire nella whitelist ciò che desidera.

Risoluzione della configurazione:
1. `--config /path/to/config.json` — file locale (flag CLI, priorità massima)
2. `--config https://example.com/config.json` — recupera da URL
3. `SLOPPY_JOE_CONFIG=...` — variabile d'ambiente (percorso file o URL)
4. Nessuna configurazione = solo controlli di esistenza + similarità + metadati

Configurazioni malformate **falliscono duramente** con messaggi di errore utilizzabili — una configurazione rotta non ricade mai silenziosamente su nessuna protezione.

Vedi [CONFIG.md](https://github.com/brennhill/sloppy-joe/blob/HEAD/CONFIG.md) per il riferimento completo al formato, modelli di integrazione CI ed esempi.

Configurazione di bootstrap:```bash
sloppy-joe init --greenfield --ecosystem npm
sloppy-joe init --from-current
sloppy-joe init --from-current --register
sloppy-joe init --register

Integrazione CI

GitHub Actions

Il modo più veloce per aggiungere sloppy-joe alla tua pipeline CI — scarica un binario precompilato da GitHub Releases (nessuna toolchain Rust richiesta):```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:~
#### Input di azione

| Input | Descrizione | Default |
|-------|-------------|---------|
| `config` | Percorso del file di configurazione o URL HTTPS | *(nessuno)* |
| `dir` | Directory del progetto da analizzare | `.` |
| `type` | Ecosistema (`npm`, `pypi`, `cargo`, `go`, `ruby`, `php`, `jvm`, `dotnet`) | rilevamento automatico |
| `deep` | Abilita i controlli di somiglianza delle dipendenze transitive | `false` |
| `paranoid` | Abilita mutazioni bitflip | `false` |
| `args` | Argomenti CLI aggiuntivi | *(nessuno)* |
| `version` | versione di sloppy-joe da installare | `latest` |

#### Esempi```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 funziona con il framework [pre-commit](https://pre-commit.com).
Aggiungilo al tuo `.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

L'hook esegue sloppy-joe check su ogni commit (e opzionalmente su push). Rileva automaticamente il tuo ecosistema dai file manifest. Passa argomenti aggiuntivi tramite args:```yaml - id: sloppy-joe args: [--config, "https://example.com/config.json"]

root@kitploit:~
Oppure usa un semplice hook di shell senza il framework:```bash
#!/bin/sh
sloppy-joe check || exit 1

Architettura

sloppy-joe utilizza un approccio generativo basato su registro per il rilevamento delle somiglianze. Invece di confrontare ogni dipendenza con un corpus statico utilizzando la distanza di modifica (che produce falsi positivi), genera mutazioni specifiche del nome di ogni dipendenza, interroga il registro per verificare se la mutazione esiste e segnala le corrispondenze esatte.``` 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:~
La similarità esegue 4 fasi:
- **Fase 0: Scope squatting** — controllo locale, senza rete. Confronta lo scope/namespace con scopes noti come sicuri tramite la distanza di Levenshtein.
- **Fase 1: Intra-manifest** — controllo locale. Segnala quando due dipendenze nello stesso manifest sono mutazioni l'una dell'altra.
- **Fase 2: Query al registry** — genera mutazioni, interroga in batch il registry per verificarne l'esistenza, memorizza nella cache i risultati (TTL di 7 giorni).
- **Fase 3: Arricchimento dei metadati** — recupera i conteggi dei download e le date di pubblicazione per le corrispondenze, per aggiungere prove ai report.

Ogni generatore di mutazioni etichetta il proprio output, quindi il tipo di controllo riportato (es. `similarity/homoglyph`) è deterministico — il generatore con la severità più alta vince quando più generatori producono lo stesso candidato.

## Affidabilità della CI

sloppy-joe è progettato per pipeline CI in cui fallimenti intermittenti sono inaccettabili.

**Riprova con backoff.** Tutte le chiamate HTTP al registry riprovano 3 volte con backoff esponenziale (200ms, 400ms, 800ms) in caso di errori transitori (5xx, timeout, errori di connessione). Un singolo problema di rete non farà fallire la build.

**Fail-closed sugli errori di query.** Se le query al registry o a OSV falliscono, sloppy-joe emette un errore bloccante `registry-unreachable` invece di saltare silenziosamente i controlli. La scansione non si basa più su soglie per ecosistema o limiti di dimensione del campione prima di bloccarsi.

**Cache di similarità.** I risultati sull'esistenza delle mutazioni vengono memorizzati nella cache per 7 giorni. Dopo la prima scansione, la maggior parte delle query viene servita dalla cache senza chiamate di rete. Solo le nuove dipendenze attivano query al registry.

**Risoluzione basata su lockfile.** Quando un lockfile supportato è presente e attendibile (`package-lock.json`, `npm-shrinkwrap.json`, `Cargo.lock`, `Gemfile.lock`, `poetry.lock` per progetti Poetry, `uv.lock` per progetti uv, `composer.lock`, `gradle.lockfile`, `packages.lock.json`), sloppy-joe risolve le versioni esatte da esso invece di indovinare dagli intervalli. I file `requirements*.txt` completamente bloccati tramite hash possono anche fornire versioni esatte bloccate, e diventano completamente attendibili quando il grafico delle dipendenze impegnato vincola il proprio `--index-url` e i valori esatti di `--extra-index-url` consentiti.

## Test

La suite di test copre i controlli di similarità, i segnali di metadati, il comportamento di OSV, l'analisi e la validazione della configurazione, la risoluzione dei lockfile, la politica di preflight per manifest e lockfile, la formattazione dei report e la logica di ripetizione HTTP.```bash
cargo test

Basato su

  • Typomania — La libreria di typosquatting della Rust Foundation, che ha ispirato l'approccio di mutazione generativa (sloppy-joe implementa i propri generatori invece di utilizzare la crate direttamente)
  • strsim — Distanza di Levenshtein, utilizzata per il rilevamento dello scope squatting
  • reqwest — Client HTTP asincrono con retry per le query ai registry
  • OSV.dev — Database di vulnerabilità noto per il rilevamento di pacchetti dannosi

Come si confronta sloppy-joe

Dove gli altri sono più forti: Socket.dev esegue un'analisi approfondita degli script di installazione con rilevamento comportamentale che va ben oltre l'approccio basato su flag di sloppy-joe. cargo-deny ha un controllo di conformità delle licenze di prim'ordine, ma ciò è intenzionalmente fuori dallo scopo di sloppy-joe perché la politica delle licenze è un problema di conformità, non un controllo di sicurezza delle dipendenze. npm audit e pip-audit sono opzioni a installazione zero per la scansione di vulnerabilità in un singolo ecosistema.

Dove sloppy-joe è diverso: È l'unico strumento che verifica che i pacchetti esistano effettivamente nei registry (catturando le allucinazioni dell'IA), esegue 11 generatori di typosquatting con falsi positivi quasi nulli, applica scelte di pacchetti canonici e mantiene la sua configurazione al di fuori del repository in modo che gli agenti IA non possano indebolire i propri controlli.

Licenza

Apache 2.0

Scarica lo strumento
--ci
--full
EcosistemaManifest richiestoLockfile / stato progetto attendibile
JavaScript / npmpackage.jsonpackage-lock.json o npm-shrinkwrap.json; npm v1 legacy bloccato per impostazione predefinita
JavaScript / pnpmpackage.jsonpnpm-lock.yaml
JavaScript / Yarnpackage.jsonyarn.lock
JavaScript / Bunpackage.jsonbun.lock
Pythonpyproject.toml, requirements*.txt, Pipfile, setup.cfg o setup.pyil percorso Poetry attendibile usa poetry.lock, il percorso uv attendibile usa uv.lock, e pip-tools con hash completo è attendibile solo quando il grafo dei requisiti committato lega esattamente --index-url e qualsiasi valore --extra-index-url; gli indici Python visibili nel repository possono essere inseriti nella whitelist tramite trusted_indexes.pypi; le modalità Python attendibili valutano un profilo di installazione selezionato alla volta (runtime per impostazione predefinita, gruppi/extras/platform/arch/version espliciti tramite CLI); i manifest legacy sono consentiti con avvisi per impostazione predefinita
RustCargo.tomlCargo.lock
Gogo.modgo.sum richiesto per dipendenze esterne
RubyGemfileGemfile.lock
PHP / Composercomposer.jsoncomposer.lock
JVM / Gradlebuild.gradle o build.gradle.ktsgradle.lockfile
JVM / Mavenpom.xmlsolo avviso: nessun percorso di lockfile locale al progetto attendibile ancora
.NET / NuGet.csprojpackages.lock.json
sloppy-joeSocket.devGuardDogPhantom Guardantislopsquat
Controllo esistenza✅✅❌✅✅
Similarità / typosquat✅✅✅✅❌
Rilevamento omoglifi✅❌❌❌❌
Scope squatting✅❌❌❌❌
Enforcement canonico✅❌❌❌❌
Gating età versione✅❌❌❌❌
Amplificazione script install✅✅❌❌❌
Esplosione dipendenze✅❌❌❌❌
Cambiamento manutentore✅✅❌❌❌
Controllo vulnerabilità OSV✅✅❌❌❌
Sicurezza config (fuori repo)✅N/D❌❌❌
Liste interne + consentite✅❌❌❌❌
npm✅✅✅✅❌
PyPI✅✅✅✅✅
Cargo✅✅❌✅❌
Go✅✅✅❌❌
Ruby✅✅✅❌❌
PHP✅🔶❌❌❌
JVM (Gradle/Maven)✅✅❌❌❌
.NET (NuGet)✅✅❌❌❌
Singolo binario✅❌❌❌❌
Open sourceApache 2.0CommercialeApache 2.0MITOSS
LinguaggioRustSaaSPythonPythonPython
Caratteristicasloppy-joeSocket.devcargo-denypip-auditnpm audit
Rilevamento di pacchetti allucinati✅❌❌❌❌
Rilevamento di typosquatting✅ 11 generatoriParziale❌❌❌
Applicazione del nome canonico✅❌❌❌❌
Scansione di vulnerabilità note✅ tramite OSV✅✅✅✅
Analisi degli script di installazioneBase (flag + no repo)✅ Analisi approfondita❌❌❌
Conformità delle licenzeOOS: conformità, non sicurezza✅✅ EccellenteOOS: conformità, non sicurezzaOOS: conformità, non sicurezza
Multi-ecosistema8 ecosisteminpm, PyPI, Go, Ruby, Java, .NETSolo RustSolo PythonSolo npm
Sicurezza per agenti AI (configurazione fuori dal repository)✅❌❌❌❌
Compatibile offline/CI✅ Funziona ovunqueRichiede la piattaforma Socket✅✅✅
Gratuito / open sourceApache 2.0Livello gratuito + a pagamentoApache 2.0Apache 2.0Integrato