
SkillSpector v2.8.2
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.
SkillSpector
Security-Scanner für AI-Agent-Skills. Erkennen Sie Schwachstellen, bösartige Muster und Sicherheitsrisiken, bevor Sie Agent-Skills installieren.
Überblick
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.
Dokumentation
- Agent-Skills vor der Installation scannen — Gehosteter Leitfaden: wann gescannt werden sollte, wie ein Bericht gelesen wird und wie Installationen gesteuert werden.
- Entwicklungsleitfaden — Architektur, Paketstruktur und Erweiterung der Analyse-Pipeline.
- Pi-Erweiterung — Installieren Sie SkillSpector als Pi-Tool, um Skills direkt aus Agent-Sitzungen heraus zu scannen.
Funktionen
- Multi-Format-Eingabe: Scannen Sie Git-Repos, URLs, ZIP-Dateien, Verzeichnisse oder einzelne Dateien
- 68 Schwachstellenmuster in 17 Kategorien: Prompt-Injection, Datenexfiltration, Privilegienerweiterung, Supply Chain, übermäßige Agency, Ausgabe-Handling, System-Prompt-Leckage, Memory-Poisoning, Tool-Missbrauch, Rogue Agent, Anti-Refusal, Trigger-Missbrauch, gefährlicher Code (AST), Taint-Tracking, YARA-Signaturen, MCP Least Privilege und MCP-Tool-Poisoning
- Zweistufige Analyse: Schnelle statische Analyse + optionale semantische Bewertung durch LLM
- Live-Schwachstellenabfragen: SC4 fragt OSV.dev für Echtzeit-CVE-Daten ab, mit automatischem Offline-Fallback
- Mehrere Ausgabeformate: Terminal-, JSON-, Markdown- und SARIF-Berichte
- Risikobewertung: Bewertung von 0-100 mit Schweregrad-Kennzeichnungen und klaren Empfehlungen
- Basislinie / Unterdrückung falsch positiver Ergebnisse: Akzeptieren Sie bekannte Befunde über eine Glob-Regel- oder Fingerprint-Basislinie, sodass erneute Scans nur neue Probleme aufzeigen (Dokumentation)
Schnellstart
Installation
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
Update later: uv tool update skillspector
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
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 (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
Grundlegende Verwendung```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
#### 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
Batch-Scanning
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.
LLM-Analyse
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.
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 |
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
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_installundfindings. Es meldet außerdemllm_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.
Konfiguration
Umgebungsvariablen
| 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 |
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.
CLI-Optionen```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]
## 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
How It Works
SkillSpector verwendet eine zweistufige Erkennungspipeline:
Stufe 1: Statische Analyse
- Schneller regex-basierter Musterabgleich über 11 statische Analysatoren
- AST-basierte Verhaltensanalyse zur Erkennung gefährlicher Aufrufe (exec, eval, subprocess usw.)
- Live-Schwachstellenabfragen über OSV.dev für bekannte CVEs in Abhängigkeiten
- Scannt alle analysierbaren Dateien im Skill
- Hohe Erkennungsrate (erfasst die meisten Probleme)
- Mittlere Präzision (einige Fehlalarme)
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.
Stufe 2: LLM-semantische Analyse (optional)
- Bewertet Kontext und Absicht
- Filtert Fehlalarme heraus
- Liefert für Menschen verständliche Erklärungen
- Verbessert die Präzision auf ~87 %
Der LLM-Prompt enthält Anti-Jailbreak-Schutzmaßnahmen, um eine Manipulation der Analyse durch bösartige Skills zu verhindern.
Live-Schwachstellenabfragen (SC4)
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.
- Kein API-Schlüssel erforderlich — OSV.dev ist kostenlos und ohne Authentifizierung nutzbar.
- Batch-Abfragen — alle Abhängigkeiten werden in einem einzigen HTTP-Aufruf geprüft.
- Automatisches Fallback — falls OSV.dev nicht erreichbar ist (air-gapped/offline), wird eine kleine eingebaute Fallback-Liste verwendet.
- Caching — Ergebnisse werden für 1 Stunde im Speicher zwischengespeichert, um redundante API-Aufrufe während einer Sitzung zu vermeiden.
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.
Vertrauensmodell und Datenabfluss
SkillSpector ist Defense-in-Depth, keine Sandbox. Wisse, was es tut und was nicht, bevor du dich darauf verlässt:
- Es führt den gescannten Skill niemals aus. Die gesamte Analyse ist statisch (Regex, Python-AST, YARA) plus optionale LLM-Bewertung von Dateiinhalten – der Code des Skills wird nie ausgeführt.
- Die LLM-Analyse sendet analysierbare Dateiinhalte an den konfigurierten Anbieter. Wenn die LLM-Analyse aktiviert ist (Standard), werden Dateiinhalte an den aktiven
SKILLSPECTOR_PROVIDER-Endpunkt gesendet. Erkannte OMS-Signaturdateien sind ausgeschlossen. Verwende--no-llm, um Inhalte lokal zu halten (nur statische Analyse). - SC4 sendet Abhängigkeitsnamen an OSV.dev. Die Supply-Chain-Prüfung fragt OSV.dev mit den Paketnamen und -versionen ab, die der Skill deklariert, um bekannte CVEs nachzuschlagen. Dies ist grundlegend für die Prüfung und läuft auch mit
--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. - Es sandboxt den Host nicht. SkillSpector kennzeichnet riskante Muster, bevor du einen Skill installierst; es enthält oder isoliert keinen Skill, den du trotzdem installierst.
Einschränkungen
- Nicht-englische Inhalte: Muster in anderen Sprachen können übersehen werden
- Bildbasierte Angriffe: Text in Bildern kann nicht analysiert werden
- Verschlüsselter/Binärcode: Kompilierte oder verschlüsselte Inhalte können nicht analysiert werden
- Laufzeitverhalten: Nur statische Analyse, keine dynamische Ausführung
- Offline-SC4: Ohne Netzwerkzugriff auf
api.osv.devverwendet SC4 eine kleine statische Fallback-Liste
Forschungshintergrund
Basiert auf der Forschung aus „Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
- Datensatz: 42.447 Skills aus großen Marktplätzen
- Verwundbar: 26,1 % enthalten mindestens eine Schwachstelle
- Hoher Schweregrad: 5,2 % zeigen wahrscheinlich böswillige Absicht
- Wichtigste Erkenntnis: Skills mit ausführbaren Skripten sind 2,12-mal häufiger verwundbar
Python-API-Integration
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:
How It Works
SkillSpector uses a two-stage detection pipeline:
Stage 1: Static Analysis
- Fast regex-based pattern matching across 11 static analyzers
- AST-based behavioral analysis detecting dangerous calls (exec, eval, subprocess, etc.)
- Live vulnerability lookups via OSV.dev for known CVEs in dependencies
- Scans all analyzer-eligible files in the skill
- High recall (catches most issues)
- Moderate precision (some false positives)
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.
Stage 2: LLM Semantic Analysis (Optional)
- Evaluates context and intent
- Filters false positives
- Provides human-readable explanations
- Improves precision to ~87%
The LLM prompt includes anti-jailbreak protections to prevent malicious skills from manipulating the analysis.
Live Vulnerability Lookups (SC4)
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.
- No API key required — OSV.dev is free and unauthenticated.
- Batch queries — all dependencies are checked in a single HTTP call.
- Automatic fallback — if OSV.dev is unreachable (air-gapped/offline), a small built-in fallback list is used.
- Caching — results are cached in-memory for 1 hour to avoid redundant API calls during a session.
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.
Trust model and data egress
SkillSpector is defense-in-depth, not a sandbox. Know what it does and does not do before relying on it:
- It never executes the scanned skill. All analysis is static (regex, Python AST, YARA) plus optional LLM evaluation of file contents — the skill's code is never run.
- LLM analysis sends analyzer-eligible file contents to the configured provider. When LLM analysis is enabled (the default), file contents are sent to the active
SKILLSPECTOR_PROVIDERendpoint. Recognized OMS signature files are excluded. Use--no-llmto keep contents local (static analysis only). - SC4 sends dependency names to OSV.dev. The supply-chain check queries OSV.dev with the package names and versions the skill declares, to look up known CVEs. This is fundamental to the check and runs even with
--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. - It does not sandbox the host. SkillSpector flags risky patterns before you install a skill; it does not contain or isolate a skill you choose to install anyway.
Limitations
- Non-English content: May miss patterns in other languages
- Image-based attacks: Cannot analyze text in images
- Encrypted/binary code: Cannot analyze compiled or encrypted content
- Runtime behavior: Static analysis only, no dynamic execution
- Offline SC4: Without network access to
api.osv.dev, SC4 uses a small static fallback list
Research Background
Based on research from "Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
- Dataset: 42,447 skills from major marketplaces
- Vulnerable: 26.1% contain at least one vulnerability
- High-severity: 5.2% show likely malicious intent
- Key finding: Skills with executable scripts are 2.12x more likely to be vulnerable
Python API Integration
Output only the translated German Markdown.## So funktioniert es
SkillSpector verwendet eine zweistufige Erkennungspipeline:
Stufe 1: Statische Analyse
- Schneller regex-basierter Musterabgleich über 11 statische Analysatoren
- AST-basierte Verhaltensanalyse zur Erkennung gefährlicher Aufrufe (exec, eval, subprocess usw.)
- Live-Schwachstellenabfragen über OSV.dev für bekannte CVEs in Abhängigkeiten
- Scannt alle für Analysen in Frage kommenden Dateien im Skill
- Hohe Erkennungsrate (erfasst die meisten Probleme)
- Mittlere Präzision (einige Fehlalarme)
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.
Stufe 2: LLM-semantische Analyse (optional)
- Bewertet Kontext und Absicht
- Filtert Fehlalarme heraus
- Liefert für Menschen verständliche Erklärungen
- Verbessert die Präzision auf ~87 %
Der LLM-Prompt enthält Anti-Jailbreak-Schutzmaßnahmen, um zu verhindern, dass bösartige Skills die Analyse manipulieren.
Live-Schwachstellenabfragen (SC4)
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.
- Kein API-Schlüssel erforderlich — OSV.dev ist kostenlos und ohne Authentifizierung nutzbar.
- Batch-Abfragen — alle Abhängigkeiten werden in einem einzigen HTTP-Aufruf geprüft.
- Automatisches Fallback — falls OSV.dev nicht erreichbar ist (Air-Gapped/Offline), wird eine kleine integrierte Fallback-Liste verwendet.
- Caching — Ergebnisse werden für 1 Stunde im Speicher zwischengespeichert, um redundante API-Aufrufe während einer Sitzung zu vermeiden.
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.
Vertrauensmodell und Datenabfluss
SkillSpector ist Defense-in-Depth, keine Sandbox. Wisse, was es tut und was nicht, bevor du dich darauf verlässt:
- Es führt den gescannten Skill niemals aus. Die gesamte Analyse ist statisch (Regex, Python-AST, YARA) plus optionale LLM-Bewertung von Dateiinhalten — der Code des Skills wird nie ausgeführt.
- Die LLM-Analyse sendet für Analysen in Frage kommende Dateiinhalte an den konfigurierten Anbieter. Wenn die LLM-Analyse aktiviert ist (Standard), werden Dateiinhalte an den aktiven
SKILLSPECTOR_PROVIDER-Endpunkt gesendet. Erkannte OMS-Signaturdateien sind ausgeschlossen. Verwende--no-llm, um Inhalte lokal zu halten (nur statische Analyse). - SC4 sendet Abhängigkeitsnamen an OSV.dev. Die Supply-Chain-Prüfung fragt OSV.dev mit den Paketnamen und -versionen ab, die der Skill deklariert, um bekannte CVEs nachzuschlagen. Dies ist grundlegend für die Prüfung und läuft auch mit
--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. - Es sandboxt den Host nicht. SkillSpector kennzeichnet riskante Muster, bevor du einen Skill installierst; es enthält oder isoliert keinen Skill, den du trotzdem installierst.
Einschränkungen
- Nicht-englische Inhalte: Muster in anderen Sprachen können übersehen werden
- Bildbasierte Angriffe: Text in Bildern kann nicht analysiert werden
- Verschlüsselter/Binärcode: Kompilierte oder verschlüsselte Inhalte können nicht analysiert werden
- Laufzeitverhalten: Nur statische Analyse, keine dynamische Ausführung
- Offline-SC4: Ohne Netzwerkzugriff auf
api.osv.devverwendet SC4 eine kleine statische Fallback-Liste
Forschungshintergrund
Basiert auf der Forschung aus „Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale" (Liu et al., 2026):
- Datensatz: 42.447 Skills aus großen Marktplätzen
- Verwundbar: 26,1 % enthalten mindestens eine Schwachstelle
- Hoher Schweregrad: 5,2 % zeigen wahrscheinlich bösartige Absicht
- Wichtigste Erkenntnis: Skills mit ausführbaren Skripten sind 2,12-mal häufiger verwundbar
Python-API-Integration```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']}")
## 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)