
Monitor automatico di sicurezza della supply chain che interroga i registri PyPI e npm, confronta le nuove release con le precedenti e utilizza l'analisi LLM per rilevare modifiche di codice dannose con avvisi su Slack.
Monitoraggio automatizzato dei principali pacchetti PyPI e npm per compromissioni della supply chain. Interroga entrambi i registry per nuove release, confronta ogni release con la precedente e utilizza un LLM (tramite Cursor Agent CLI) per classificare le differenze come benigne o malevole. I risultati malevoli attivano un avviso su Slack.
Entrambi gli ecosistemi sono monitorati per impostazione predefinita. Usa --no-pypi o --no-npm per disabilitarne uno.
Ogni ecosistema esegue il proprio thread di polling ma condivide la pipeline di analisi e notifica.
┌─── PyPI ──────────────────────┐ ┌─── npm ───────────────────────┐
│ │ │ │
│ changelog_since_serial() │ │ CouchDB _changes feed │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │ Tutti gli │─┐ │ │ │ Tutte le │─┐ │
│ │ eventi PyPI│ │ │ │ │ modifiche │ │ │
│ └────────────┘ ▼ │ │ │ npm │ │ │
│ hugovk ──► Watchlist │ │ └────────────┘ ▼ │
│ │ │ │ download-counts ─► Watchlist │
│ solo eventi "new release" │ │ nuove versioni dall'ultimo │
└───────────────┬───────────────┘ │ epoch │
│ └───────────────┬───────────────┘
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ Scarica vecchia + │ │ Scarica vecchia + │
│ nuova (sdist + │ │ nuova (tarball) │
│ wheel) │ └───────────────────┘
└───────────────────┘
│ │
└─────────────────┬─────────────────┘
▼
┌───────────────┐
│ Report diff │
│ unificato (.md)│
└───────┬───────┘
▼
┌───────────────┐ ◄── Analisi LLM
│ Cursor Agent │ (sola lettura)
│ CLI (ask mode)│
└───────┬───────┘
│
verdetto?
│
malevolo │
▼
┌───────────────┐
│ Avviso Slack │
└───────────────┘
L'analisi LLM è istruita per cercare:
pip install -r requirements.txt (la libreria standard copre la maggior parte dello strumento; requests è usata per i caricamenti su Slack)agent standalone, non l'IDEWindows (PowerShell):
irm 'https://cursor.com/install?win32=true' | iex
macOS / Linux:
curl https://cursor.com/install -fsS | bash
Verifica con:
agent --version
Devi essere autenticato con Cursor (agent login o imposta CURSOR_API_KEY).
Inserisci il tuo token bot Slack in etc/slack.json:
{
"url": "https://hooks.slack.com/services/...",
"bot_token": "xoxb-...",
"channel": "C01XXXXXXXX"
}
Il bot necessita dell'ambito chat:write sul canale di destinazione. Il campo channel è l'ID del canale Slack dove vengono pubblicati gli avvisi.
# Passaggio singolo: analizza le release degli ultimi ~10 minuti
python monitor.py --once
# Continuo: monitora i primi 1000 pacchetti (entrambi gli ecosistemi), polling ogni 5 min
python monitor.py --top 1000 --interval 300
# Produzione: monitora i primi 15000, avvisa su Slack
python monitor.py --top 15000 --interval 300 --slack
# Solo npm, primi 5000
python monitor.py --no-pypi --npm-top 5000
# Solo PyPI
python monitor.py --no-npm
| File | Scopo |
|---|---|
monitor.py | Orchestratore principale — esegue il polling di PyPI + npm, diff, analisi, notifica (thread paralleli) |
pypi_monitor.py | Poller standalone del changelog PyPI (usato per esplorazione) |
package_diff.py | Scarica e confronta due versioni di qualsiasi pacchetto PyPI o npm |
analyze_diff.py | Invia un diff a Cursor Agent CLI, analizza il verdetto |
top_pypi_packages.py | Recupera e elenca i primi N pacchetti PyPI per conteggio download |
slack.py | Client API Slack (SendMessage, PostFile) |
etc/slack.json | Credenziali bot Slack |
last_serial.yaml | Stato di polling persistito (serial PyPI + sequence/epoch npm) |
logs/ | File di log giornalieri (monitor_YYYYMMDD.log) |
python monitor.py [OPZIONI]
Opzioni:
--top N Numero di pacchetti migliori da monitorare per ecosistema (default: 15000)
--interval SECS Intervallo di polling in secondi (default: 300)
--once Singolo passaggio sugli eventi recenti, poi esci
--slack Abilita avvisi Slack per risultati malevoli
--model MODEL Sovrascrivi modello LLM (default: composer-2-fast)
--debug Abilita logging DEBUG (include output raw dell'agente)
Opzioni PyPI:
--no-pypi Disabilita monitoraggio PyPI
--serial N Serial del changelog PyPI da cui iniziare
Opzioni npm:
--no-npm Disabilita monitoraggio npm
--npm-top N Primi N pacchetti npm da monitorare (default: uguale a --top)
--npm-seq N Sequence di replica npm da cui iniziare
PyPI e npm eseguono ciascuno il proprio thread di polling. Lo stato di polling (serial PyPI, sequence + epoch npm) viene persistito in last_serial.yaml in modo che il monitor riprenda da dove si era interrotto dopo un riavvio.
Pipeline PyPI:
--interval secondi, chiama changelog_since_serial() — una singola chiamata API che restituisce tutti gli eventi dall'ultimo controllo"new release" corrispondenti alla watchlist