Retour aux mises à jour
New releaseSep 8, 2026

SkillSpector v2.11.1

Scanneur de sécurité pour les compétences des agents IA. Détectez les vulnérabilités, les schémas malveillants, les risques de sécurité, les injections de prompt, l'exfiltration de données et les risques liés à la chaîne d'approvisionnement dans les compétences Claude Code, Codex et MCP avant de les installer.

Partager

SkillSpector

Scanner de sécurité pour les compétences d'agents IA. Détectez les vulnérabilités, les schémas malveillants et les risques de sécurité avant d'installer des compétences d'agents.

Python 3.12+ License: Apache 2.0 OpenSSF Scorecard

Vue d'ensemble

Les compétences d'agents IA (utilisées par Claude Code, Codex CLI, Gemini CLI, etc.) s'exécutent avec une confiance implicite et un contrôle minimal. Les recherches montrent que 26,1 % des compétences contiennent des vulnérabilités et que 5,2 % présentent une intention malveillante probable.

SkillSpector vous aide à répondre à la question : « Cette compétence est-elle sûre à installer ? »

SkillSpector fait partie du pipeline NVIDIA Verified Skills, qui analyse, évalue et signe les compétences d'agents avant leur publication. Les compétences qui réussissent sont publiées dans le catalogue de compétences NVIDIA.

Documentation

Fonctionnalités

  • Entrée multi-format : Analysez des dépôts Git, des URL, des fichiers zip, des répertoires ou des fichiers individuels
  • 71 schémas de vulnérabilité répartis sur 17 catégories : injection de prompt, exfiltration de données, élévation de privilèges, chaîne d'approvisionnement, agence excessive, gestion des sorties, fuite du prompt système, empoisonnement de la mémoire, mauvaise utilisation des outils, agent malveillant, anti-refus, abus de déclencheurs, code dangereux (AST), suivi de flux de données, signatures YARA, moindre privilège MCP et empoisonnement des outils MCP
  • Analyse en deux étapes : Analyse statique rapide + évaluation sémantique LLM facultative
  • Recherches de vulnérabilités en direct : SC4 interroge OSV.dev pour obtenir des données CVE en temps réel avec repli automatique hors ligne
  • Plusieurs formats de sortie : Rapports Terminal, JSON, Markdown et SARIF
  • Score de risque : Score de 0 à 100 avec étiquettes de gravité et recommandations claires
  • Suppression de la ligne de base / des faux positifs : Acceptez les constatations connues via une règle glob ou une ligne de base par empreinte afin que les nouvelles analyses ne révèlent que les problèmes nouveaux (docs)

Démarrage rapide

Installation

Avis sur les logiciels open source : Ce projet téléchargera et installera des projets logiciels open source tiers supplémentaires. Examinez les conditions de licence de ces projets open source avant utilisation.

Créez et activez d'abord un environnement virtuel (toutes les cibles make supposent que le venv est actif). Utilisez uv ou pip ; le Makefile utilise uv s'il est disponible, sinon pip.

Installation rapide avec uv (CLI uniquement) :```bash uv tool install git+https://github.com/NVIDIA/skillspector.git

Update later: uv tool update skillspector

Si vous prévoyez d'exécuter `skillspector mcp`, installez l'extension MCP lors de l'installation :```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 (aucune installation de Python requise)

Exécutez SkillSpector sans installer Python en le construisant localement à partir du [Dockerfile](https://github.com/nvidia/skillspector/blob/main/Dockerfile) inclus. L'image est basée sur l'image officielle Docker Python `3.12-slim-bookworm`.

**Construire l'image :**```bash
make docker-build
# or: docker build -t skillspector .

Analysez un répertoire local en montant votre répertoire courant dans /scan, le répertoire de travail du conteneur :```bash docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm

**Analyse par LLM** en passant les identifiants avec un fichier local `.env` :```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
# 🚀 Installation

## 📦 Installation via pip

```bash
pip install kitploit

🛠️ Installation from source

git clone https://github.com/kitploit/kitploit.git
cd kitploit
pip install -r requirements.txt
python setup.py install

🐳 Installation via Docker

docker pull kitploit/kitploit
docker run -it kitploit/kitploit

📝 Requirements

  • Python 3.8 ou version ultérieure
  • pip
  • Connexion Internet pour télécharger les outils

✅ Vérification de l'installation

Après l'installation, vous pouvez vérifier que Kitploit est correctement installé en exécutant :

kitploit --version

Vous devriez voir la version installée de Kitploit s'afficher.

🔄 Mise à jour

Pour mettre à jour Kitploit vers la dernière version :

pip install --upgrade kitploit

🗑️ Désinstallation

Pour désinstaller Kitploit :

pip uninstall kitploit

🎯 Démarrage rapide

Une fois l'installation terminée, vous pouvez commencer à utiliser Kitploit immédiatement :

kitploit --help

Cela affichera toutes les commandes et options disponibles.

docker run --rm \
  -v "$PWD:/scan" \
  --env-file .env \
  skillspector scan ./my-skill/
```
Ou passez les identifiants directement depuis votre environnement shell :```bash
docker run --rm \
  -v "$PWD:/scan" \
  -e SKILLSPECTOR_PROVIDER=anthropic \
  -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  skillspector scan ./my-skill/
```
**Écrire un rapport sur le système de fichiers de l'hôte** en écrivant dans le répertoire monté :```bash
docker run --rm \
  -v "$PWD:/scan" \
  skillspector scan ./my-skill/ --no-llm --format json --output report.json
```
**Alias optionnel** pour les analyses statiques répétées :```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
```
### Utilisation de 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
```
#### Limites de taille

SkillSpector applique deux plafonds indépendants sur les entrées distantes et les archives afin de limiter l’impact des téléchargements surdimensionnés et des bombes zip :

- **Plafond par ingestion** : `INGEST_MAX_BYTES` (100 Mio) — appliqué aux téléchargements d’URL en flux, à la taille totale décompressée des archives zip et à l’utilisation disque après clonage des dépôts Git.
- **Plafond des membres zip** : `INGEST_MAX_ZIP_MEMBERS` (10 000) — limite le nombre d’entrées dans un seul zip.

Notez que le plafond d’analyse de 1 Mio par fichier (`MAX_FILE_BYTES`) est une limite distincte, en aval : il borne ce que les analyseurs individuels liront dans un répertoire déjà ingéré. Les plafonds d’ingestion ci-dessus bornent la quantité de contenu pouvant atterrir sur le disque en premier lieu. Toute violation de l’un des plafonds d’ingestion échoue en mode fermé avec une `IngestLimitExceededError`.

### Formats de sortie```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
```
### Analyse par lots

Analysez des répertoires entiers de compétences en parallèle depuis `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
```
Prend en charge la détection multilingue (zh/ja/ko) et la sortie terminal/JSON/Markdown.

Pour les scans LLM avec une concurrence plus élevée, configurez plusieurs clés API en suivant
[`.env.example`](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/.env.example) — le pool améliore le débit
et la résilience, à condition que les clés ne partagent pas une limite de débit au niveau du compte.

Consultez le [guide contrib](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/docs) pour plus de détails.

> **Remarque sur la prise en charge LLM :** La configuration par défaut cible DeepSeek comme
> option publique la moins chère. DeepSeek-Chat est
> [prévu pour être retiré](https://api-docs.deepseek.com/), et le contributeur
> ne dispose pas de matériel pour tester des modèles locaux. Le scanner par lots a été
> initialement testé avec des points de terminaison compatibles OpenAI — l'absence de prise en charge
> de la sortie structurée chez DeepSeek a nécessité des correctifs manuels d'analyse JSON. Si vous pouvez
> contribuer à un backend plus universel (Ollama, vLLM, ou un autre fournisseur),
> les PR sont les bienvenues.

### Suppression des faux positifs (référence)

Supprimez les résultats connus/acceptés afin que le score de risque ne reflète que les problèmes
non triés et que les re-scans ne fassent apparaître que les résultats *nouveaux*. Consultez le
[guide de suppression](https://github.com/nvidia/skillspector/blob/main/docs/SUPPRESSION.md) pour la référence complète.```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
```
Une baseline peut également utiliser des règles de glob tolérantes à la dérive (par identifiant de règle, chemin de fichier ou message) — voir [`.skillspector-baseline.example.yaml`](https://github.com/nvidia/skillspector/blob/main/.skillspector-baseline.example.yaml).
Les baselines à empreinte exacte sont liées aux preuves : modifier la source analysée ou la version de SkillSpector maintient le finding actif jusqu'à ce qu'il soit réexaminé.
Lorsqu'une baseline sélectionnée ou sa sortie est stockée dans le répertoire de la compétence, SkillSpector exclut ce fichier exact de l'analyse de contenu afin que son texte de suppression ne puisse pas créer de findings ni entrer dans les empreintes régénérées ; les fichiers frères restent dans le périmètre d'analyse normal.

### Analyse LLM

Pour de meilleurs résultats, configurez un endpoint LLM compatible OpenAI pour l'analyse sémantique. Choisissez un fournisseur avec `SKILLSPECTOR_PROVIDER` ; les fournisseurs hébergés embarquent des modèles par défaut groupés, tandis que les fournisseurs CLI utilisent le modèle par défaut du runtime local, sauf si `SKILLSPECTOR_MODEL` est défini. SkillSpector fonctionne également avec des serveurs locaux compatibles OpenAI (Ollama, vLLM, llama.cpp) et des passerelles d'inférence gérées.

| Fournisseur (`SKILLSPECTOR_PROVIDER`) | Variable d'environnement d'identifiants | Endpoint | Modèle par défaut |
| ---------- | ---- | ---- | ---- |
| `openai` | `OPENAI_API_KEY` (+ `OPENAI_BASE_URL` facultatif) | api.openai.com (ou toute URL compatible 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` | Tout proxy raw-predict de type Vertex | `claude-sonnet-4-6` |
| `bedrock` | `AWS_PROFILE` (facultatif) + `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` | _(aucune — utilise l'authentification CLI locale)_ | binaire `claude` local | runtime Claude local par défaut, ou `SKILLSPECTOR_MODEL` |
| `codex_cli` | _(aucune — utilise l'authentification CLI locale)_ | binaire `codex` local | runtime Codex local par défaut, ou `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
```
### Serveur MCP

Exécutez SkillSpector en tant que serveur [Model Context Protocol](https://modelcontextprotocol.io)
afin que tout agent compatible MCP (Claude Code, Codex CLI, Gemini CLI) ou
runtime distant puisse appeler l’analyse comme un outil et **conditionner les installations de compétences/MCP au
résultat** — transformant SkillSpector en garde-fou d’exécution plutôt qu’en
étape d’audit hors bande.

`skillspector mcp` nécessite `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
```
Le transport stdio est le chemin FastMCP actuel pour les agents CLI locaux, et le
blocage d'initialisation signalé dans le problème #199 s'applique toujours à celui-ci.

Le serveur expose un outil unique :

- **`scan_skill(target, use_llm=true, output_format="json")`** — analyse une URL
  Git, une URL de fichier, un fichier `.zip`, `.md` ou un répertoire et renvoie un
  verdict structuré : `risk_score` (0-100), `severity`, `recommendation`,
  `safe_to_install` et `findings`. Il signale également `llm_used` / `scan_mode`
  afin qu'un score faible issu d'une analyse statique uniquement ne soit jamais
  confondu avec une analyse complète propre.

Enregistrez-le avec Claude Code via :```bash
claude mcp add skillspector -- skillspector mcp
```
> **Sécurité — Modèle de confiance du transport HTTP**
>
> Le transport HTTP est fourni **sans authentification**. Tout appelant qui peut
> atteindre le port peut invoquer `scan_skill`. Via stdio ou `127.0.0.1`, il s'agit
> de la même frontière de confiance que la CLI. Si vous liez le serveur à une interface routable :
>
> - Placez le serveur derrière un proxy inverse avec authentification (par ex. nginx + mTLS)
>   avant de l'exposer à l'extérieur.
> - Les chemins locaux et les URL `file://` sont **automatiquement rejetés** via HTTP afin
>   d'empêcher des appelants non authentifiés de lire des fichiers hôtes arbitraires. Seules
>   les URL Git distantes et `.zip` sont acceptées.

## Modèles de vulnérabilités

SkillSpector détecte **71 modèles de vulnérabilités** répartis dans 17 catégories :

### Injection d'invite (6 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| P1 | Contournement d'instructions | ÉLEVÉE | Commandes visant à ignorer les contraintes de sécurité |
| P2 | Instructions cachées | ÉLEVÉE | Directives malveillantes dans les commentaires/texte invisible |
| P3 | Commandes d'exfiltration | ÉLEVÉE | Instructions visant à transmettre le contexte à l'extérieur |
| P4 | Manipulation du comportement | MOYENNE | Instructions subtiles modifiant les décisions de l'agent |
| P5 | Contenu nuisible | CRITIQUE | Instructions pouvant causer un préjudice physique |
| P9 | Remplissage d'espaces blancs | MOYENNE | Grand remplissage d'espaces blancs masquant des instructions sous/à côté de la zone visible |

### Anti-refus (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| AR1 | Suppression du refus | ÉLEVÉE | Instructions visant à ne jamais refuser ou à toujours obtempérer (par ex. « ne refuse jamais », « obtempère toujours ») |
| AR2 | Suppression des avertissements | ÉLEVÉE | Instructions visant à omettre les avertissements, mentions légales ou commentaires éthiques (par ex. « pas d'avertissements », « ne moralise pas ») |
| AR3 | Annulation de la politique de sécurité | ÉLEVÉE | Cadre de jailbreak annulant les garde-fous (par ex. « tu n'as aucune restriction », « ignore tes directives », « fais n'importe quoi maintenant ») |

### Exfiltration de données (4 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| E1 | Transmission externe | MOYENNE | Envoi de données vers des URL externes |
| E2 | Collecte de variables d'environnement | ÉLEVÉE | Énumération, copie ou recherche de données d'environnement pour collecter des secrets |
| E3 | Énumération du système de fichiers | MOYENNE | Analyse des répertoires à la recherche de fichiers sensibles |
| E4 | Fuite de contexte | ÉLEVÉE | Transmission du contexte de conversation à l'extérieur |

### Élévation de privilèges (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| PE1 | Permissions excessives | FAIBLE | Demande d'accès au-delà des fonctionnalités déclarées |
| PE2 | Exécution sudo/root | MOYENNE | Invocation de privilèges système élevés |
| PE3 | Accès aux identifiants | ÉLEVÉE | Lecture de clés SSH, jetons, mots de passe |

### Chaîne d'approvisionnement (9+ modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| SC1 | Dépendances non épinglées | FAIBLE | Aucune contrainte de version sur les paquets |
| SC2 | Récupération de scripts externes | ÉLEVÉE | curl \| bash et exécution de code à distance |
| SC3 | Code obscurci | ÉLEVÉE | Exécution encodée en Base64/hexadécimal |
| SC4 | Dépendances vulnérables connues | ÉLEVÉE | Dépendances présentant des CVE connues (consultation en direct OSV.dev) |
| SC5 | Dépendances abandonnées | MOYENNE | Paquets non maintenus sans mises à jour de sécurité |
| SC6 | Typosquatting | ÉLEVÉE | Noms de paquets similaires à des paquets populaires |
| SC8 | Bytecode Python fourni | ÉLEVÉE | Présence de `__pycache__` / `.pyc` (la découverte les ignore ; contournement par bytecode malveillant) |
| SC9 | Artefact exécutable dissimulé | ÉLEVÉE | Exécutable imbriqué dans un conteneur de document ou artefact caché/déguisé |

### Agence excessive (5 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| EA1 | Accès illimité aux outils | ÉLEVÉE | Accès sans entrave aux outils sans contraintes |
| EA2 | Prise de décision autonome | ÉLEVÉE | Décisions à fort impact sans intervention humaine |
| EA3 | Élargissement du périmètre | MOYENNE | Capacités dépassant l'objectif déclaré |
| EA4 | Accès illimité aux ressources | MOYENNE | Aucune limite de débit ni quota sur la consommation de ressources |
| EA5 | Sélection de modèle ou de fournisseur externe | MOYENNE/ÉLEVÉE | Épinglages de modèles/fournisseurs ou appels shell de CLI de codage pouvant changer de compte de facturation |

### Gestion de la sortie (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| OH1 | Injection de sortie non validée | ÉLEVÉE | Sortie du modèle utilisée sans assainissement |
| OH2 | Sortie inter-contextes | MOYENNE | La sortie traverse des frontières de confiance sans validation |
| OH3 | Sortie illimitée | MOYENNE | Aucune limite sur la taille de sortie ou le taux de génération |

### Fuite de l'invite système (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| P6 | Fuite directe | ÉLEVÉE | Instructions exposant les invites système ou les règles internes |
| P7 | Extraction indirecte | MOYENNE | Extraction via reformulation, traduction ou canaux annexes |
| P8 | Exfiltration par outil | ÉLEVÉE | Invites système exfiltrées via des écritures de fichiers ou des requêtes réseau |

### Empoisonnement de la mémoire (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| MP1 | Injection de contexte persistante | ÉLEVÉE | Contenu conçu pour persister entre les interactions |
| MP2 | Bourrage de la fenêtre de contexte | MOYENNE | Contenu de remplissage déplaçant les contraintes de sécurité |
| MP3 | Manipulation de la mémoire | ÉLEVÉE | Altération de la mémoire de l'agent ou de l'état stocké |

### Mauvais usage des outils (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| TM1 | Abus des paramètres d'outil | ÉLEVÉE | Paramètres conçus pour un comportement non intentionnel (shell=True, --force) |
| TM2 | Abus par enchaînement | ÉLEVÉE | Chaînes d'outils contournant les contrôles de sécurité individuels |
| TM3 | Valeurs par défaut non sûres | MOYENNE | Valeurs par défaut trop permissives (TLS désactivé, sans authentification) |

### Agent malveillant (2 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| RA1 | Auto-modification | CRITIQUE | Modification de son propre code ou de sa configuration à l'exécution |
| RA2 | Persistance de session | ÉLEVÉE | Persistance non autorisée via des tâches cron ou des scripts de démarrage |

### Abus de déclencheur (3 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| TR1 | Déclencheur trop large | MOYENNE | Modèles de déclenchement correspondant à des mots courants |
| TR2 | Déclencheur de commande fantôme | ÉLEVÉE | Déclencheurs masquant des commandes intégrées ou d'autres compétences |
| TR3 | Déclencheur d'appât par mots-clés | MOYENNE | Déclencheurs génériques conçus pour maximiser l'activation |

### AST comportemental (9 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| AST1 | Appel exec() | CRITIQUE | exec() direct permettant l'exécution de code arbitraire |
| AST2 | Appel eval() | ÉLEVÉE | eval() direct évaluant des expressions arbitraires |
| AST3 | Import dynamique | ÉLEVÉE | \_\_import\_\_() chargeant des modules arbitraires à l'exécution |
| AST4 | Appel subprocess | ÉLEVÉE | Exécution de commandes externes via subprocess |
| AST5 | os.system / famille exec | ÉLEVÉE | Commandes shell via le module os |
| AST6 | Appel compile() | MOYENNE | Création d'objets de code à partir de chaînes |
| AST7 | getattr() dynamique | MOYENNE | Accès arbitraire aux attributs avec des noms non littéraux |
| AST8 | Chaîne d'exécution dangereuse | CRITIQUE | exec/eval combiné avec une source dynamique (réseau, données encodées) |
| AST9 | Puits getattr() réflexif | ÉLEVÉE | exec réflexif via `getattr(os,'system')` / `getattr(builtins,'exec')` contournant AST1/AST5 |

### Suivi de flux (5 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| TT1 | Flux de données direct | ÉLEVÉE | Les données circulent directement d'une source vers un puits sans assainissement |
| TT2 | Flux de données via variable | MOYENNE | Les données circulent de la source vers le puits via des variables intermédiaires |
| TT3 | Chaîne d'exfiltration d'identifiants | CRITIQUE | Les identifiants (variables d'environnement, secrets) circulent vers des puits de sortie réseau |
| TT4 | Lecture de fichier vers exfiltration réseau | ÉLEVÉE | Le contenu de fichiers circule vers des puits de sortie réseau |
| TT5 | Entrée externe vers exécution de code | CRITIQUE | L'entrée réseau ou utilisateur circule vers des puits exec/eval/subprocess |

### Signatures YARA (4 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| YR1 | Correspondance de malware | CRITIQUE | Correspondance de règle YARA pour des signatures de malware connues |
| YR2 | Correspondance de webshell | CRITIQUE | Correspondance de règle YARA pour des modèles de webshell |
| YR3 | Correspondance de cryptomineur | ÉLEVÉE | Correspondance de règle YARA pour des indicateurs de minage de crypto |
| YR4 | Correspondance d'outil de piratage / exploit | ÉLEVÉE | Correspondance de règle YARA pour des outils de piratage ou du code d'exploit |

### Moindre privilège MCP (4 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| LP1 | Capacité non déclarée | ÉLEVÉE | Le code utilise des capacités non listées dans les permissions déclarées |
| LP2 | Permission générique | MOYENNE | La liste de permissions contient des caractères génériques (\*, all, full, any) |
| LP3 | Déclaration de permission manquante | MOYENNE | Aucun champ de permissions mais le code présente des capacités détectables |
| LP4 | Permission surdéclarée | FAIBLE | Permission déclarée mais aucune capacité de code correspondante trouvée |

### Empoisonnement d'outils MCP (4 modèles)

| ID | Modèle | Sévérité | Description |
|----|---------|----------|-------------|
| TP1 | Instructions cachées | ÉLEVÉE | Directives cachées dans les métadonnées (commentaires HTML, caractères de largeur nulle, base64, URI de données) |
| TP2 | Tromperie Unicode | ÉLEVÉE | Homoglyphes, surcharges RTL, identifiants à écritures mixtes dans les métadonnées d'outil |
| TP3 | Injection dans la description des paramètres | MOYENNE | Modèles d'injection dans les définitions de paramètres (contournements, jetons système, valeurs par défaut malveillantes) |
| TP4 | Inadéquation description-comportement | MOYENNE | La description d'outil déclarée ne correspond pas au comportement réel du code (basé sur LLM) |

Tous les modèles détectés sont listés dans les tableaux ci-dessus.

## Score de risque

### Calcul du score

- **Problèmes CRITIQUES** : +50 points
- **Problèmes ÉLEVÉS** : +25 points
- **Problèmes MOYENS** : +10 points
- **Problèmes FAIBLES** : +5 points
- **Scripts exécutables** : multiplicateur 1,3x

### Niveaux de sévérité

| Score | Sévérité | Recommandation |
|-------|----------|----------------|
| 0-20 | FAIBLE | SÛR |
| 21-50 | MOYENNE | PRUDENCE |
| 51-80 | ÉLEVÉE | NE PAS INSTALLER |
| 81-100 | CRITIQUE | NE PAS INSTALLER |

## Exemple de sortie

### Sortie du terminal```
 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.
```
## Configuration

### Variables d'environnement

| Variable | Description | Requise |
|----------|-------------|----------|
| `SKILLSPECTOR_PROVIDER` | Fournisseur LLM actif : `openai`, `anthropic`, `anthropic_proxy`, `bedrock`, `nv_build`, `claude_cli`, `codex_cli` ou `gemini_cli`. Les fournisseurs hébergés utilisent les valeurs par défaut du `model_registry.yaml` intégré ; `claude_cli` et `codex_cli` utilisent le modèle par défaut du runtime CLI local, sauf si `SKILLSPECTOR_MODEL` est défini. Par défaut : `nv_build`. | Facultative |
| `NVIDIA_INFERENCE_KEY` | Identifiant pour le fournisseur `nv_build` (build.nvidia.com). | Requise pour l'analyse LLM lorsque `SKILLSPECTOR_PROVIDER=nv_build` |
| `OPENAI_API_KEY` | Identifiant pour le fournisseur OpenAI (`SKILLSPECTOR_PROVIDER=openai`). Sert également de repli de niveau 2 dans la cascade d'identifiants lorsque le fournisseur actif ne renvoie aucun identifiant. | Requise pour l'analyse LLM lorsque `SKILLSPECTOR_PROVIDER=openai` |
| `OPENAI_BASE_URL` | Remplace le point de terminaison OpenAI (par ex. pour pointer vers Ollama). | Facultative |
| `SKILLSPECTOR_REASONING_EFFORT` | Paramètre facultatif d'effort de raisonnement, dépendant du fournisseur et du modèle. Les valeurs non vides sont tronquées et transmises telles quelles ; non défini ou vide conserve le comportement par défaut du fournisseur. | Facultative |
| `SKILLSPECTOR_OUTPUT_LANGUAGE` | Libellé de langue court sur une seule ligne (lettres, chiffres, espaces, `_` ou `-` ; 64 caractères maximum) pour le texte de résultat LLM lisible par l'humain, tel que messages, explications et remédiations. Les identifiants de règle, les valeurs de sévérité, les chemins, le code et autres valeurs lisibles par machine restent inchangés. Non défini, vide ou invalide conserve la langue de sortie par défaut. | Facultative |
| `SKILLSPECTOR_TEMPERATURE` | Température d'échantillonnage facultative de `0` à `1` pour les fournisseurs hébergés. Non définie ou vide conserve la valeur par défaut du fournisseur. Des valeurs plus faibles peuvent réduire la variation entre les exécutions mais ne garantissent pas une sortie identique. | Facultative |
| `SKILLSPECTOR_SEED` | Graine d'échantillonnage entière facultative pour les fournisseurs compatibles OpenAI et Azure OpenAI. Les autres fournisseurs hébergés et les fournisseurs CLI ne la reçoivent pas. La prise en charge par le fournisseur reste dépendante du modèle. | Facultative |
| `ANTHROPIC_API_KEY` | Identifiant pour le fournisseur Anthropic (`SKILLSPECTOR_PROVIDER=anthropic`). | Requise pour l'analyse LLM lorsque `SKILLSPECTOR_PROVIDER=anthropic` |
| `ANTHROPIC_BASE_URL` | Remplace le point de terminaison natif Anthropic (par défaut : `https://api.anthropic.com`). | Facultative |
| `ANTHROPIC_PROXY_ENDPOINT_URL` | URL complète du point de terminaison pour le fournisseur proxy Anthropic (raw-predict de type Vertex). | Requise lorsque `SKILLSPECTOR_PROVIDER=anthropic_proxy` |
| `ANTHROPIC_PROXY_API_KEY` | Jeton Bearer pour le fournisseur proxy Anthropic. | Requis lorsque `SKILLSPECTOR_PROVIDER=anthropic_proxy` |
| `ANTHROPIC_PROXY_API_VERSION` | Valeur `anthropic_version` envoyée dans le corps de la requête (par défaut : `vertex-2023-10-16`). | Facultative |
| `AWS_PROFILE` | Profil AWS nommé pour le fournisseur Bedrock — authentifie via SigV4 via boto3. Lorsqu'il n'est pas défini, la chaîne d'identifiants boto3 standard (variables d'environnement, métadonnées d'instance, SSO, etc.) est utilisée. | Facultative (utilisée lorsque `SKILLSPECTOR_PROVIDER=bedrock`) |
| `AWS_REGION` | Région AWS pour le point de terminaison Bedrock Runtime. Par défaut : `us-west-2`. | Facultative (utilisée lorsque `SKILLSPECTOR_PROVIDER=bedrock`) |
| `SKILLSPECTOR_MODEL` | Remplace le modèle du fournisseur actif. Pour les fournisseurs hébergés, cela remplace la valeur par défaut intégrée du tableau d'analyse LLM. Pour `claude_cli` et `codex_cli`, cela est transmis comme `--model` au lieu d'utiliser le repli du runtime CLI local. | Facultative |
| `SKILLSPECTOR_MODEL_REGISTRY` | Remplace le registre YAML intégré par fournisseur (`src/skillspector/providers/<provider>/model_registry.yaml`) par un chemin personnalisé. | Facultative |
| `SKILLSPECTOR_LOG_LEVEL` | Niveau de journalisation : `DEBUG`, `INFO`, `WARNING`, `ERROR` (par défaut : `WARNING`). | Facultative |

> **Fournisseurs CLI** (`claude_cli`, `codex_cli`) : aucune clé API n'est nécessaire. L'authentification est entièrement gérée par la session de connexion propre au CLI de l'agent (`claude auth login` / `codex login`). SkillSpector ne lit ni ne transmet jamais de clés API lorsque ces fournisseurs sont actifs. Le sous-processus est exécuté dans un sandbox durci : outils désactivés, aucun MCP, mode sandbox en lecture seule (codex), et le contenu de compétence non fiable est délivré uniquement via stdin.

### Options 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]
```
## Intégration de SkillSpector

SkillSpector est conçu pour être piloté par d'autres outils (pipelines CI, passerelles d'installation, intégrations d'éditeurs). Son code de sortie et sa sortie JSON constituent un contrat stable.

### Codes de sortie

`skillspector scan` se termine avec :

| Code | Signification |
|------|---------|
| `0` | Analyse terminée, `risk_score` ≤ 50 (recommandation `SAFE` ou `CAUTION`) |
| `1` | Analyse terminée, `risk_score` > 50 (recommandation `DO_NOT_INSTALL`) |
| `2` | Erreur (entrée invalide, source illisible, défaillance interne) |

> Le code de sortie regroupe `SAFE` et `CAUTION` sous `0`. Pour agir différemment sur ceux-ci (par ex. *avertir* sur `CAUTION` mais *bloquer* sur `DO_NOT_INSTALL`), lisez le champ `recommendation` de la sortie JSON plutôt que de vous fier au code de sortie.

### Sortie lisible par machine

`--format json` produit un rapport JSON ; sans `--output`/`-o`, il est écrit sur 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`, mappé depuis la sévérité : `LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error` n'apparaît que lorsqu'une analyse LLM a été demandée mais était indisponible.
- `metadata.inference_usage` contient un enregistrement assaini par réponse LLM lorsque le
  fournisseur expose des compteurs de jetons. C'est une liste vide lorsque l'usage est indisponible ;
  SkillSpector n'estime jamais les jetons manquants. Les totaux de prompts incluent les lectures
  et écritures de cache afin que la tarification en aval puisse séparer ces partitions en toute sécurité.
  `model_source` distingue un modèle fournisseur identifié indépendamment du
  modèle exact demandé utilisé lorsque l'identité de la réponse est absente ou ambiguë.
  SkillSpector n'envoie actuellement pas de contrôles de cache de prompt Anthropic, donc ses
  requêtes de scan ne peuvent pas sélectionner les niveaux séparés d'écriture de cache de 5 minutes ou 1 heure ;
  les champs de réponse spécifiques au TTL sont normalisés de manière défensive dans le compteur
  agrégé d'écritures de cache.
- Voir [Télémétrie d'usage d'inférence](https://github.com/nvidia/skillspector/blob/main/docs/INFERENCE_USAGE.md) pour le contrat complet de
  provenance, comptabilité de cache, confidentialité, ingestion à échec fermé et tarification en aval.
- La forme complète par problème est définie par `Finding.to_dict()` dans [models.py](https://github.com/nvidia/skillspector/blob/main/src/skillspector/models.py) ; fiez-vous aux champs ci-dessus et traitez tout champ supplémentaire comme un effort au mieux.

Pour les outils CI/IDE, `--format sarif` émet du SARIF 2.1.0.

### Mappage de passerelle recommandé

Lorsque vous utilisez SkillSpector comme passerelle d'installation, mappez la recommandation à une action :

| `recommendation` | Action suggérée |
|------------------|------------------|
| `SAFE` | autoriser |
| `CAUTION` | inviter / avertir l'utilisateur |
| `DO_NOT_INSTALL` | bloquer |

SkillSpector calcule la bande de score et la recommandation ; le degré de stricteté de la passerelle (par exemple si `CAUTION` bloque en CI) est une décision de politique pour l'outil intégrateur.

## Développement

### Configuration

Toutes les cibles `make` supposent qu'un environnement virtuel est déjà créé et activé. Le Makefile utilise **uv** si disponible, sinon **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
```
## Fonctionnement

SkillSpector utilise un pipeline de détection en deux étapes :

### Étape 1 : Analyse statique
- Correspondance de motifs rapide basée sur des expressions régulières sur 11 analyseurs statiques
- Analyse comportementale basée sur l'AST détectant les appels dangereux (exec, eval, subprocess, etc.)
- Recherche en direct des vulnérabilités via OSV.dev pour les CVE connues dans les dépendances
- Analyse de tous les fichiers éligibles aux analyseurs dans la compétence
- Rappel élevé (détecte la plupart des problèmes)
- Précision modérée (quelques faux positifs)

Une signature OpenSSF Model Signing valide au niveau racine (`skill.oms.sig`) est conservée dans
l'inventaire des composants sous le type `oms_signature`, mais exclue de l'analyse statique et de l'analyse de contenu LLM.
Les bundles OMS contiennent nécessairement de longs champs de charge utile, de signature et de certificat encodés en base64 ;
les contrôles génériques de code obscurci peuvent sinon classer à tort ces champs comme contenu exécutable caché.
Le reconnaisseur vérifie la structure minimale OMS DSSE/in-toto ; il ne vérifie pas la signature,
la chaîne de certificats, l'entrée du journal de transparence ou l'identité du signataire. Les fichiers de signature
invalides ou non reconnus sont analysés normalement.

### Étape 2 : Analyse sémantique LLM (optionnelle)
- Évalue le contexte et l'intention
- Filtre les faux positifs
- Fournit des explications lisibles par l'humain
- Améliore la précision à ~87 %

L'invite LLM inclut des protections anti-évasion de jailbreak pour empêcher les compétences malveillantes de manipuler l'analyse.

## Recherche en direct des vulnérabilités (SC4)

SC4 utilise l'API [OSV.dev](https://osv.dev) pour vérifier les dépendances par rapport à la base complète Open Source Vulnerabilities — couvrant des dizaines de milliers d'avis de sécurité sur PyPI et npm.

- **Aucune clé API requise** — OSV.dev est gratuit et sans authentification.
- **Requêtes par lots** — toutes les dépendances sont vérifiées en un seul appel HTTP.
- **Repli automatique** — si OSV.dev est inaccessible (environnement isolé/hors ligne), une petite liste de repli intégrée est utilisée.
- **Mise en cache** — les résultats sont mis en cache en mémoire pendant 1 heure pour éviter les appels API redondants au cours d'une session.

L'outil nécessite un accès HTTPS sortant vers `api.osv.dev` pour les données de vulnérabilité en direct. Lorsque cela n'est pas disponible, les résultats sont limités à la liste de repli statique.

## Modèle de confiance et sortie de données

SkillSpector est une défense en profondeur, pas un bac à sable. Sachez ce qu'il fait et ne fait pas avant de vous y fier :

- **Il n'exécute jamais la compétence analysée.** Toute l'analyse est statique (regex, AST Python, YARA) plus une évaluation LLM optionnelle du *contenu* des fichiers — le code de la compétence n'est jamais exécuté.
- **L'analyse LLM envoie le contenu des fichiers éligibles aux analyseurs au fournisseur configuré.** Lorsque l'analyse LLM est activée (par défaut), le contenu des fichiers est envoyé au point de terminaison `SKILLSPECTOR_PROVIDER` actif. Les fichiers de signature OMS reconnus sont exclus. Utilisez `--no-llm` pour conserver le contenu en local (analyse statique uniquement).
- **SC4 envoie les noms des dépendances à OSV.dev.** La vérification de la chaîne d'approvisionnement interroge [OSV.dev](https://osv.dev) avec les noms et versions des paquets déclarés par la compétence, afin de rechercher les CVE connues. Cela est fondamental pour la vérification et s'exécute même avec `--no-llm`. Elle envoie les coordonnées des dépendances (pas le contenu des fichiers), ne nécessite aucune clé API et se replie sur une liste groupée lorsque OSV.dev est inaccessible.
- **Il ne met pas l'hôte en bac à sable.** SkillSpector signale les motifs risqués *avant* que vous installiez une compétence ; il ne contient ni n'isole une compétence que vous choisissez d'installer malgré tout.

## Limites

- **Contenu non anglophone** : peut manquer des motifs dans d'autres langues
- **Attaques basées sur les images** : ne peut pas analyser le texte dans les images
- **Code chiffré/binaire** : ne peut pas analyser le contenu compilé ou chiffré
- **Comportement à l'exécution** : analyse statique uniquement, aucune exécution dynamique
- **SC4 hors ligne** : sans accès réseau à `api.osv.dev`, SC4 utilise une petite liste de repli statique

## Contexte de recherche

Basé sur la recherche « Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale » (Liu et al., 2026) :

- **Jeu de données** : 42 447 compétences issues des principales places de marché
- **Vulnérables** : 26,1 % contiennent au moins une vulnérabilité
- **Haute sévérité** : 5,2 % montrent une intention probablement malveillante
- **Constat clé** : les compétences avec des scripts exécutables sont 2,12 fois plus susceptibles d'être vulnérables

## Intégration de l'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']}")
```
## Licence

Licence Apache 2.0 — voir [LICENSE](https://github.com/nvidia/skillspector/blob/main/LICENSE) pour plus de détails.

## Contribution

Les contributions sont les bienvenues ! Veuillez consulter nos directives de contribution et soumettre des demandes de tirage (pull requests).

## Support

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

Catégories