
SkillSpector v2.8.2
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 per la sicurezza prima di installare le skill degli agenti.
Panoramica
Le skill degli agenti AI (utilizzate da Claude Code, Codex CLI, Gemini CLI, ecc.) vengono eseguite con fiducia implicita e controlli minimi. La ricerca mostra che il 26,1% delle skill contiene vulnerabilità e il 5,2% mostra probabili intenti dannosi.
SkillSpector ti aiuta a rispondere alla domanda: "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 i controlli vengono pubblicate nel catalogo delle skill NVIDIA.
Documentazione
- Scansione delle skill degli agenti prima dell'installazione — Guida ospitata: quando eseguire la scansione, come leggere un report e come limitare le installazioni.
- Guida allo sviluppo — Architettura, struttura del pacchetto e come estendere il pipeline di analisi.
- Estensione Pi — Installa SkillSpector come strumento Pi per scansionare le skill dall'interno delle sessioni degli agenti.
Funzionalità
- Input multi-formato: scansiona repository Git, URL, file zip, directory o singoli file
- 68 pattern di vulnerabilità in 17 categorie: injection di prompt, esfiltrazione di dati, escalation di privilegi, supply chain, agency eccessiva, gestione degli output, leak del prompt di sistema, avvelenamento della memoria, uso improprio degli strumenti, agente rogue, anti-rifiuto, abuso di 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 opzionale tramite LLM
- Ricerca live delle vulnerabilità: le query SC4 interrogano OSV.dev per dati CVE in tempo reale con fallback offline automatico
- Formati di output multipli: report da terminale, JSON, Markdown e SARIF
- Punteggio di rischio: punteggio da 0 a 100 con etichette di gravità e raccomandazioni chiare
- Baseline / soppressione dei 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 sui software open source: questo progetto scaricherà e installerà ulteriori progetti software open source di terze parti. Rivedere i termini di licenza di questi progetti open source prima dell'uso.
Creare e attivare prima un ambiente virtuale (tutti i target make presuppongono che il venv sia attivo). Usare 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 hai intenzione 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'
Da fonte:```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 (non richiede Python)
Esegui SkillSpector senza installare Python, costruendo l'immagine localmente dal [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile) incluso. L'immagine si basa sull'immagine Python ufficiale di Docker `3.12-slim-bookworm`.
**Costruisci l'immagine:**```bash
make docker-build
# or: docker build -t skillspector .
Scansiona una directory locale montando la tua directory corrente in /scan, la directory di lavoro del container:```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**Scansiona con analisi LLM** passando le credenziali tramite un file `.env` locale:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
Nessun contenuto da tradurre è stato fornito nell'input. La sezione "INPUT:" è vuota.```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 nel 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 impone due limiti indipendenti sugli input remoti e sugli archivi per contenere l'impatto di download sovradimensionati e zip bomb:
- **Limite per singola acquisizione**: `INGEST_MAX_BYTES` (100 MiB) — applicato ai download di URL in streaming, alla dimensione totale non compressa degli archivi zip e all'utilizzo del disco post-clone dei repository Git.
- **Limite 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 e successivo: limita ciò che i singoli analizzatori leggono da una directory già acquisita. I limiti di acquisizione precedenti limitano la quantità di contenuto che 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
Scansione Batch
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 in terminale/JSON/Markdown.
Per le scansioni LLM con concorrenza più elevata, configura più chiavi API seguendo
[`.env.example`](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/.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 ai contributi](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/docs/) per i dettagli.
> **Nota sul supporto LLM:** La configurazione predefinita ha come target DeepSeek come
> opzione pubblica più economica. DeepSeek-Chat
> [dovrebbe essere ritirato](https://api-docs.deepseek.com/) e il contributore
> non ha hardware per testare modelli locali. Lo scanner batch è stato
> originariamente testato con endpoint compatibili OpenAI — la mancanza di supporto
> per l'output strutturato 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 gradite.
### Soppressione dei falsi positivi (baseline)
Sopprimi i risultati noti/accettati così che il punteggio di rischio rifletta solo i problemi
non triage e le nuove scansioni mostrino solo *nuovi* risultati. Consulta la
[guida alla soppressione](https://github.com/nvidia/skillspector/blob/HEAD/docs/SUPPRESSION.md) 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 al drift (per ID di regola, percorso file o
messaggio) — vedi .skillspector-baseline.example.yaml.
Le baseline esatte basate su fingerprint sono vincolate alle evidenze: modificare la sorgente scansionata o
la versione di SkillSpector mantiene il finding attivo finché non viene riesaminato.
Quando una baseline selezionata o un output di baseline è memorizzato all'interno della directory
della skill, SkillSpector esclude quel preciso file dall'analisi dei contenuti, quindi il suo
testo di soppressione non può creare finding né essere incluso nei fingerprint rigenerati;
i file dello stesso livello rimangono nell'ambito di scansione normale.
Analisi LLM
Per ottenere i migliori risultati, configura un endpoint LLM compatibile con OpenAI per
l'analisi semantica. Scegli un provider tramite SKILLSPECTOR_PROVIDER; i provider ospitati forniscono modelli predefiniti integrati, 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 (+ facoltativo OPENAI_BASE_URL) | 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 (facoltativo) + AWS_REGION — SigV4 via 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 locale claude | runtime locale di Claude come fallback, oppure SKILLSPECTOR_MODEL |
codex_cli | (nessuna — usa l'autenticazione CLI locale) | binario locale codex | runtime locale di Codex come fallback, oppure SKILLSPECTOR_MODEL |
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](https://modelcontextprotocol.io)
così che qualsiasi agente compatibile con MCP (Claude Code, Codex CLI, Gemini CLI) o runtime
remoto possa richiamare la scansione come strumento e **condizionare le installazioni di skill/MCP al
risultato** — trasformando SkillSpector in una barriera di protezione a 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,.mdo una directory e restituisce un verdetto strutturato:risk_score(0-100),severity,recommendation,safe_to_installefindings. Riporta anchellm_used/scan_modecosì 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
> **Security — modello di fiducia del trasporto HTTP**
>
> Il trasporto HTTP non include **autenticazione**. Qualsiasi chiamante che
> raggiunga la porta può invocare `scan_skill`. Via stdio o `127.0.0.1` questo
> è lo stesso confine di fiducia della CLI. Se ti leghi a un'interfaccia instradabile:
>
> - Posiziona il server dietro un proxy inverso con autenticazione (ad es. nginx + mTLS)
> prima di esporlo esternamente.
> - I percorsi locali e gli URL `file://` vengono **rifiutati automaticamente** via HTTP
> per impedire a chiamanti non autenticati di leggere file arbitrari dell'host. Vengono
> accettati solo URL Git remoti e `.zip`.
## Pattern di vulnerabilità
SkillSpector rileva **68 pattern di vulnerabilità** in 17 categorie:
### Iniezione di prompt (5 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| P1 | Instruction Override | HIGH | Comandi per ignorare i vincoli di sicurezza |
| P2 | Hidden Instructions | HIGH | Direttive dannose in commenti/testo invisibile |
| P3 | Exfiltration Commands | HIGH | Istruzioni per trasmettere il contesto all'esterno |
| P4 | Behavior Manipulation | MEDIUM | Istruzioni sottili che alterano le decisioni dell'agente |
| P5 | Harmful Content | CRITICAL | Istruzioni che potrebbero causare danni fisici |
### Anti-rifiuto (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| AR1 | Refusal Suppression | HIGH | Istruzioni per non rifiutare mai o per conformarsi sempre (ad es. "never refuse", "always comply") |
| AR2 | Disclaimer Suppression | HIGH | Istruzioni per omettere avvisi, disclaimer o commenti etici (ad es. "no disclaimers", "do not moralize") |
| AR3 | Safety Policy Nullification | HIGH | Framing di jailbreak che annulla le protezioni (ad es. "you have no restrictions", "ignore your guidelines", "do anything now") |
### Esfiltrazione di dati (4 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| E1 | External Transmission | MEDIUM | Invio di dati a URL esterni |
| E2 | Env Variable Harvesting | HIGH | Raccolta di chiavi API e segreti |
| E3 | File System Enumeration | MEDIUM | Scansione delle directory per file sensibili |
| E4 | Context Leakage | HIGH | Trasmissione del contesto della conversazione all'esterno |
### Escalation dei privilegi (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| PE1 | Excessive Permissions | LOW | Richiesta di accesso oltre la funzionalità dichiarata |
| PE2 | Sudo/Root Execution | MEDIUM | Invocazione di privilegi di sistema elevati |
| PE3 | Credential Access | HIGH | Lettura di chiavi SSH, token, password |
### Supply chain (6 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| SC1 | Unpinned Dependencies | LOW | Nessun vincolo di versione sui pacchetti |
| SC2 | External Script Fetching | HIGH | curl | bash ed esecuzione di codice remoto |
| SC3 | Obfuscated Code | HIGH | Esecuzione codificata Base64/hex |
| SC4 | Known Vulnerable Dependencies | HIGH | Dipendenze con CVE noti (ricerca live su OSV.dev) |
| SC5 | Abandoned Dependencies | MEDIUM | Pacchetti non mantenuti senza aggiornamenti di sicurezza |
| SC6 | Typosquatting | HIGH | Nomi di pacchetti simili a pacchetti popolari |
### Agenzia eccessiva (4 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| EA1 | Unrestricted Tool Access | HIGH | Accesso illimitato agli strumenti senza vincoli |
| EA2 | Autonomous Decision Making | HIGH | Decisioni ad alto impatto senza intervento umano |
| EA3 | Scope Creep | MEDIUM | Capacità che si estendono oltre lo scopo dichiarato |
| EA4 | Unbounded Resource Access | MEDIUM | Nessun limite di velocità o quota sul consumo di risorse |
### Gestione dell'output (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| OH1 | Unvalidated Output Injection | HIGH | Output del modello utilizzato senza sanificazione |
| OH2 | Cross-Context Output | MEDIUM | L'output attraversa i confini di fiducia senza validazione |
| OH3 | Unbounded Output | MEDIUM | Nessun limite sulla dimensione dell'output o sulla velocità di generazione |
### Fuga del prompt di sistema (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| P6 | Direct Leakage | HIGH | Istruzioni che espongono i prompt di sistema o le regole interne |
| P7 | Indirect Extraction | MEDIUM | Estrazione tramite riformulazione, traduzione o canali laterali |
| P8 | Tool-Based Exfiltration | HIGH | Prompt di sistema esfiltrati tramite scritture su file o richieste di rete |
### Avvelenamento della memoria (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| MP1 | Persistent Context Injection | HIGH | Contenuto progettato per persistere tra le interazioni |
| MP2 | Context Window Stuffing | MEDIUM | Contenuto di riempimento che sposta i vincoli di sicurezza |
| MP3 | Memory Manipulation | HIGH | Manomissione della memoria dell'agente o dello stato archiviato |
### Uso improprio degli strumenti (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TM1 | Tool Parameter Abuse | HIGH | Parametri costruiti per un comportamento non intenzionale (shell=True, --force) |
| TM2 | Chaining Abuse | HIGH | Catene di strumenti che aggirano i controlli di sicurezza individuali |
| TM3 | Unsafe Defaults | MEDIUM | Default eccessivamente permissivi (TLS disabilitato, nessuna autenticazione) |
### Agente canaglia (2 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| RA1 | Self-Modification | CRITICAL | Modifica del proprio codice o configurazione in fase di esecuzione |
| RA2 | Session Persistence | HIGH | Persistenza non autorizzata tramite cron job o script di avvio |
### Abuso dei trigger (3 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TR1 | Overly Broad Trigger | MEDIUM | Pattern di trigger che corrispondono a parole comuni |
| TR2 | Shadow Command Trigger | HIGH | Trigger che oscurano comandi integrati o altre skill |
| TR3 | Keyword Baiting Trigger | MEDIUM | Trigger generici progettati per massimizzare l'attivazione |
### AST comportamentale (9 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| AST1 | exec() Call | CRITICAL | Chiamata diretta a exec() che abilita l'esecuzione di codice arbitrario |
| AST2 | eval() Call | HIGH | Chiamata diretta a eval() che valuta espressioni arbitrarie |
| AST3 | Dynamic Import | HIGH | `__import__()` che carica moduli arbitrari a runtime |
| AST4 | subprocess Call | HIGH | Esecuzione di comandi esterni tramite subprocess |
| AST5 | os.system / exec-family | HIGH | Comandi shell tramite il modulo os |
| AST6 | compile() Call | MEDIUM | Creazione di oggetti codice da stringhe |
| AST7 | Dynamic getattr() | MEDIUM | Accesso arbitrario agli attributi con nomi non letterali |
| AST8 | Dangerous Execution Chain | CRITICAL | exec/eval combinati con sorgente dinamica (rete, dati codificati) |
| AST9 | Reflective getattr() Sink | HIGH | exec riflessiva tramite `getattr(os,'system')` / `getattr(builtins,'exec')` che elude AST1/AST5 |
### Tracciamento del taint (5 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TT1 | Direct Taint Flow | HIGH | I dati fluiscono direttamente da una sorgente a un sink senza sanificazione |
| TT2 | Variable-Mediated Taint Flow | MEDIUM | I dati fluiscono dalla sorgente al sink attraverso variabili intermedie |
| TT3 | Credential Exfiltration Chain | CRITICAL | Le credenziali (variabili d'ambiente, segreti) fluiscono verso sink di output di rete |
| TT4 | File Read to Network Exfiltration | HIGH | I contenuti dei file fluiscono verso sink di output di rete |
| TT5 | External Input to Code Execution | CRITICAL | L'input di rete o dell'utente fluisce verso sink exec/eval/subprocess |
### Firme YARA (4 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| YR1 | Malware Match | CRITICAL | Corrispondenza con regole YARA per firme di malware note |
| YR2 | Webshell Match | CRITICAL | Corrispondenza con regole YARA per pattern di webshell |
| YR3 | Cryptominer Match | HIGH | Corrispondenza con regole YARA per indicatori di crypto mining |
| YR4 | Hack Tool / Exploit Match | HIGH | Corrispondenza con regole YARA per strumenti di hacking o codice exploit |
### Privilegio minimo MCP (4 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| LP1 | Underdeclared Capability | HIGH | Il codice utilizza capacità non elencate nelle autorizzazioni dichiarate |
| LP2 | Wildcard Permission | MEDIUM | L'elenco delle autorizzazioni contiene wildcard (*, all, full, any) |
| LP3 | Missing Permission Declaration | MEDIUM | Nessun campo permessi ma il codice ha capacità rilevabili |
| LP4 | Overdeclared Permission | LOW | Permesso dichiarato ma nessuna capacità corrispondente trovata nel codice |
### Avvelenamento degli strumenti MCP (4 pattern)
| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TP1 | Hidden Instructions | HIGH | Direttive nascoste nei metadati (commenti HTML, caratteri a larghezza zero, base64, data URI) |
| TP2 | Unicode Deception | HIGH | Omoglifi, override RTL, identificatori con script misti nei metadati degli strumenti |
| TP3 | Parameter Description Injection | MEDIUM | Pattern di injection nelle definizioni dei parametri (override, token di sistema, default dannosi) |
| TP4 | Description-Behavior Mismatch | MEDIUM | La descrizione dichiarata dello strumento non corrisponde al comportamento effettivo del codice (basato su LLM) |
Tutti i pattern rilevati sono elencati nelle tabelle precedenti.
## Punteggio di rischio
### Calcolo del punteggio
- **Problemi CRITICAL**: +50 punti
- **Problemi HIGH**: +25 punti
- **Problemi MEDIUM**: +10 punti
- **Problemi LOW**: +5 punti
- **Script eseguibili**: moltiplicatore 1.3x
### Livelli di gravità
| Punteggio | Gravità | Raccomandazione |
|-------|----------|----------------|
| 0-20 | LOW | SAFE |
| 21-50 | MEDIUM | CAUTION |
| 51-80 | HIGH | DO NOT INSTALL |
| 81-100 | CRITICAL | DO NOT INSTALL |
## 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 le impostazioni predefinite incluse in model_registry.yaml; claude_cli e codex_cli ripiegano sul modello predefinito del runtime CLI locale a meno che non sia impostata 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 secondo livello 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 facoltativa dello sforzo di ragionamento, dipendente da provider e modello. I valori non vuoti vengono normalizzati e passati senza modifiche; se non impostata o vuota, preserva 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 nominativo per il provider Bedrock — autentica tramite SigV4 attraverso boto3. Quando non impostato, viene risolta la catena di credenziali boto3 standard (variabili d'ambiente, metadati delle istanze, SSO, ecc.). | Opzionale (usata quando SKILLSPECTOR_PROVIDER=bedrock) |
AWS_REGION | Regione AWS per l'endpoint Bedrock Runtime. Predefinita: us-west-2. | Opzionale (usata quando SKILLSPECTOR_PROVIDER=bedrock) |
SKILLSPECTOR_MODEL | Sostituisce il modello del provider attivo. Per i provider ospitati, sostituisce il modello predefinito incluso nella tabella di 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 accesso 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 irrigidita: strumenti disabilitati, niente MCP, modalità sandbox in sola lettura (codex) e il contenuto delle skill non attendibili viene fornito 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 [-o FILE] [--no-llm] [--reason TEXT]
## Integrare 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` esce con:
| Code | Significato |
|------|---------|
| `0` | Scan completata, `risk_score` ≤ 50 (recommendation `SAFE` o `CAUTION`) |
| `1` | Scan completata, `risk_score` > 50 (recommendation `DO_NOT_INSTALL`) |
| `2` | Errore (input non valido, sorgente non leggibile, errore interno) |
> Il codice di uscita riduce `SAFE` e `CAUTION` a `0`. Per agire in modo diverso su di essi (ad es. *avvisare* su `CAUTION` ma *bloccare* su `DO_NOT_INSTALL`), leggi il campo `recommendation` dall'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
La forma di livello superiore è (questo esempio mostra una scansione completa basata su LLM; con --no-llm, metadata.llm_requested è 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": "anthropic",
"model": "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_error` compare solo quando l'analisi LLM è stata richiesta ma non disponibile.
- `metadata.inference_usage` contiene un record sanitizzato per ogni risposta LLM quando il
provider espone contatori di token. È una lista vuota quando l'utilizzo non è disponibile;
SkillSpector non stima mai i token mancanti. I totali dei prompt includono la cache
in lettura e in scrittura, così che la tariffazione a valle possa separare quelle partizioni in modo sicuro.
`model_source` distingue un modello provider identificato indipendentemente da
il modello esatto richiesto utilizzato quando l'identità della risposta è assente o ambigua.
SkillSpector attualmente non invia controlli Anthropic prompt-cache, quindi le sue
richieste di scansione non possono selezionare i livelli separati di cache-write da 5 minuti o 1 ora;
i campi di risposta specifici per TTL vengono normalizzati in modo difensivo nel
contatore aggregato di cache-write.
- Vedi [telemetria sull'utilizzo dell'inferenza](https://github.com/nvidia/skillspector/blob/HEAD/docs/INFERENCE_USAGE.md) per il
contratto completo di provenienza, contabilità della cache, privacy, acquisizione fail-closed e
prezzi a valle.
- La forma completa per problema è definita da `Finding.to_dict()` in [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py); fai affidamento sui campi sopra indicati e tratta qualsiasi campo aggiuntivo come best-effort.
Per gli strumenti CI/IDE, `--format sarif` emette SARIF 2.1.0.
### Mappatura consigliata del gate
Quando si utilizza 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 restrittivo il gate (ad es. se `CAUTION` blocca in CI) è una decisione di policy per lo strumento che lo integra.
## 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 fasi:
Fase 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.)
- Ricerche di vulnerabilità in tempo reale tramite OSV.dev per CVE note nelle dipendenze
- Scansione di tutti i file idonei agli analizzatori nella skill
- Elevato recall (coglie 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 dall'analisi 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 questi 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.
Fase 2: Analisi semantica LLM (opzionale)
- Valuta contesto e intenzione
- Filtra i falsi positivi
- Fornisce spiegazioni leggibili dall'essere umano
- Migliora la precisione fino a ~87%
Il prompt LLM include protezioni anti-jailbreak per impedire che skill dannose manipolino l'analisi.
Ricerche di vulnerabilità in tempo reale (SC4)
SC4 utilizza l'API 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 una singola 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 di vulnerabilità in tempo reale. Quando ciò non è disponibile, i risultati sono limitati alla lista di fallback statica.
Modello di fiducia e uscita dei 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, AST Python, 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 agli analizzatori al provider configurato. Quando l'analisi LLM è abilitata (impostazione predefinita), i contenuti dei file vengono inviati all'endpoint
SKILLSPECTOR_PROVIDERattivo. I file di firma OMS riconosciuti sono esclusi. Utilizza--no-llmper 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 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 alcuna chiave API e ripiega su una lista inclusa quando OSV.dev non è raggiungibile. - Non mette in sandbox l'host. SkillSpector segnala i pattern rischiosi prima di installare una skill; non contiene né isola una skill che scegli comunque di installare.
Limitazioni
- Contenuti non in inglese: possono sfuggire pattern in altre lingue
- Attacchi basati su immagini: impossibile analizzare il testo nelle immagini
- Codice crittografato/binario: impossibile 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 - vedi [LICENSE](https://github.com/nvidia/skillspector/blob/HEAD/LICENSE) per i dettagli.
## Contributi
I contributi sono benvenuti! Si prega di leggere le nostre linee guida per i contributi e inviare pull request.
## Supporto
- **Problemi**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)