Назад к обновлениям
New releaseAug 8, 2026

SkillSpector v2.8.2

Сканер безопасности для навыков ИИ-агентов. Обнаруживает уязвимости, вредоносные паттерны, риски безопасности, промпт-инъекции, эксфильтрацию данных и риски цепочки поставок в навыках Claude Code, Codex и MCP до их установки.

Поделиться

SkillSpector

Сканер безопасности для навыков ИИ-агентов. Обнаруживайте уязвимости, вредоносные паттерны и риски безопасности перед установкой навыков агентов.

Python 3.12+ License: Apache 2.0

Обзор

Навыки ИИ-агентов (используемые Claude Code, Codex CLI, Gemini CLI и др.) выполняются с неявным доверием и минимальной проверкой. Исследования показывают, что 26.1% навыков содержат уязвимости, а 5.2% демонстрируют вероятные вредоносные намерения.

SkillSpector помогает ответить на вопрос: «Безопасно ли устанавливать этот навык?»

SkillSpector является частью конвейера NVIDIA Verified Skills, который сканирует, оценивает и подписывает навыки агентов перед публикацией. Навыки, прошедшие проверку, публикуются в каталоге навыков NVIDIA.

Документация

Возможности

  • Мультиформатный ввод: сканирование Git-репозиториев, URL-адресов, zip-файлов, каталогов или отдельных файлов
  • 68 паттернов уязвимостей в 17 категориях: инъекция в промпт, утечка данных, повышение привилегий, цепочка поставок, избыточные полномочия, обработка выходных данных, утечка системного промпта, отравление памяти, нецелевое использование инструментов, недобросовестный агент, анти-отказ, злоупотребление триггерами, опасный код (AST), taint-анализ, сигнатуры YARA, минимальные привилегии MCP и отравление инструментов MCP
  • Двухэтапный анализ: быстрый статический анализ + опциональная семантическая оценка LLM
  • Живой поиск уязвимостей: SC4 запрашивает OSV.dev для получения актуальных данных о CVE с автоматическим офлайн-фолбэком
  • Несколько форматов вывода: отчёты в терминал, JSON, Markdown и SARIF
  • Оценка риска: оценка от 0 до 100 с метками серьёзности и чёткими рекомендациями
  • Базовый уровень / подавление ложных срабатываний: принимайте известные находки через базовый уровень glob-правил или отпечатков, чтобы повторные сканирования показывали только новые проблемы (документация)

Быстрый старт

Установка

Уведомление об открытом ПО: Этот проект загрузит и установит дополнительные сторонние проекты с открытым исходным кодом. Перед использованием ознакомьтесь с условиями лицензий этих проектов.

Сначала создайте и активируйте виртуальное окружение (все цели make предполагают, что venv активен). Используйте uv или pip; Makefile использует uv, если он доступен, иначе pip.

Быстрая установка с помощью uv (только CLI):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git

Update later: uv tool update skillspector

Если вы планируете запускать `skillspector mcp`, установите дополнительный пакет MCP при установке:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'

Из исходного кода:```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 (Python не требуется)

Запустите SkillSpector без установки Python, собрав его локально из включённого [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile). Образ основан на официальном Docker-образе Python `3.12-slim-bookworm`.

**Соберите образ:**```bash
make docker-build
# or: docker build -t skillspector .

Сканируйте локальную директорию, смонтировав вашу текущую директорию в /scan — рабочую директорию контейнера:```bash docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm

**Сканирование с анализом LLM** путем передачи учетных данных через локальный файл `.env`:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF

[No content provided for translation.]```bash docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/

Или передайте учетные данные напрямую из вашего окружения shell:```bash
docker run --rm \
  -v "$PWD:/scan" \
  -e SKILLSPECTOR_PROVIDER=anthropic \
  -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  skillspector scan ./my-skill/

Запишите отчет в файловую систему хоста, записав в смонтированный каталог:```bash docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json

**Необязательный псевдоним** для повторных статических сканирований:```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm

Базовое использование```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

#### Ограничения размера

SkillSpector накладывает два независимых ограничения на удалённые и архивные входные данные, чтобы ограничить влияние чрезмерно больших загрузок и zip-бомб:

- **Лимит приёма**: `INGEST_MAX_BYTES` (100 МиБ) — применяется к потоковой загрузке по URL, общему несжатому размеру zip-архивов и использованию диска Git-репозиториями после клонирования.
- **Лимит элементов zip**: `INGEST_MAX_ZIP_MEMBERS` (10 000) — ограничивает количество записей в одном zip-архиве.

Обратите внимание, что предел анализа 1 МиБ на файл (`MAX_FILE_BYTES`) — это отдельное, более позднее ограничение: оно ограничивает то, что отдельные анализаторы будут читать из уже принятого каталога. Лимиты приёма, указанные выше, ограничивают, какой объём контента вообще может попасть на диск. Нарушение любого из этих лимитов приёма приводит к безопасному отказу с ошибкой `IngestLimitExceededError`.

### Форматы вывода```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

Пакетное сканирование

Сканируйте целые каталоги навыков параллельно из 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

Поддерживает многоязычное обнаружение (zh/ja/ko) и вывод в терминал/JSON/Markdown.

Для LLM-сканирований с более высокой степенью параллелизма настройте несколько ключей API в соответствии с
[`.env.example`](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/.env.example) — пул повышает пропускную способность
и отказоустойчивость при условии, что ключи не разделяют общий лимит на уровне аккаунта.

Подробнее см. в [руководстве для контрибьюторов](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/docs/).

> **Примечание о поддержке LLM:** Конфигурация по умолчанию ориентирована на DeepSeek как на
> самый дешёвый публичный вариант. DeepSeek-Chat
> [ожидается к прекращению поддержки](https://api-docs.deepseek.com/), и у контрибьютора
> нет оборудования для тестирования локальных моделей. Пакетный сканер
> изначально тестировался с OpenAI-совместимыми конечными точками — отсутствие у DeepSeek
> поддержки структурированного вывода потребовало ручных патчей для разбора JSON. Если вы можете
> предложить более универсальный бэкенд (Ollama, vLLM или другого провайдера),
> PR очень приветствуются.

### Подавление ложных срабатываний (базовый уровень)

Подавляйте известные/принятые находки, чтобы оценка риска отражала только нерассмотренные
проблемы, а повторные сканирования показывали только *новые* находки. См.
[руководство по подавлению](https://github.com/nvidia/skillspector/blob/HEAD/docs/SUPPRESSION.md) для полного справочника.```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

Базовая линия также может использовать устойчивые к дрейфу glob-правила (по идентификатору правила, пути к файлу или сообщению) — см. .skillspector-baseline.example.yaml. Точные базовые линии отпечатков привязаны к фактическим данным: при изменении сканируемого исходного кода или версии SkillSpector находка остаётся активной, пока не будет пересмотрена. Когда выбранная базовая линия или выходные данные базовой линии хранятся внутри каталога навыка, SkillSpector исключает этот конкретный файл из анализа содержимого, чтобы его текст подавления не мог создавать находки или попадать в регенерируемые отпечатки; соседние файлы остаются в обычной области сканирования.

LLM-анализ

Для наилучших результатов настройте LLM-эндпоинт, совместимый с OpenAI, для семантического анализа. Выберите провайдера с помощью SKILLSPECTOR_PROVIDER; облачные провайдеры поставляются со встроенными моделями по умолчанию, а CLI-провайдеры откатываются к модели по умолчанию локальной среды выполнения, если не задан SKILLSPECTOR_MODEL. SkillSpector также работает с локальными OpenAI-совместимыми серверами (Ollama, vLLM, llama.cpp) и управляемыми шлюзами инференса.

Провайдер (SKILLSPECTOR_PROVIDER)Переменная окружения для учётных данныхЭндпоинтМодель по умолчанию
openaiOPENAI_API_KEY (+ необязательный OPENAI_BASE_URL)api.openai.com (или любой OpenAI-совместимый URL)gpt-5.4
anthropicANTHROPIC_API_KEYapi.anthropic.comclaude-opus-4-6
anthropic_proxyANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URLЛюбой прокси raw-predict в стиле Vertexclaude-sonnet-4-6
bedrockAWS_PROFILE (необязательно) + AWS_REGION — SigV4 через boto3AWS Bedrock Runtimeus.anthropic.claude-sonnet-4-6-20250915-v1:0
nv_buildNVIDIA_INFERENCE_KEYbuild.nvidia.comdeepseek-ai/deepseek-v4-flash
claude_cli(нет — используется локальная аутентификация CLI)локальный бинарник claudeзапасная модель Claude из локальной среды выполнения или SKILLSPECTOR_MODEL
codex_cli(нет — используется локальная аутентификация CLI)локальный бинарник codexзапасная модель Codex из локальной среды выполнения или 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-сервер

Запускайте SkillSpector как [Model Context Protocol](https://modelcontextprotocol.io)
сервер, чтобы любой MCP-совместимый агент (Claude Code, Codex CLI, Gemini CLI) или удалённая среда
выполнения могла вызывать сканирование как инструмент и **ставить установку скиллов/MCP в
зависимость от результата** — превращая SkillSpector в защитный механизм времени выполнения вместо
автономного шага аудита.

`skillspector mcp` требует `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

Транспорт stdio — это текущий путь FastMCP для локальных CLI-агентов, и зависание при инициализации, о котором сообщалось в issue #199, по-прежнему актуально.

Сервер предоставляет единственный инструмент:

  • scan_skill(target, use_llm=true, output_format="json") — сканирует Git URL, файловый URL, .zip, .md-файл или каталог и возвращает структурированный вердикт: risk_score (0-100), severity, recommendation, safe_to_install и findings. Он также сообщает llm_used / scan_mode, чтобы низкий балл при чисто статическом сканировании никогда не был ошибочно принят за результат полного сканирования.

Зарегистрируйте его в Claude Code через:```bash claude mcp add skillspector -- skillspector mcp

> **Безопасность — модель доверия HTTP-транспорта**
>
> HTTP-транспорт поставляется **без аутентификации**. Любой вызывающий, который может
> подключиться к порту, может вызвать `scan_skill`. Через stdio или `127.0.0.1` это
> та же граница доверия, что и у CLI. Если вы привязываетесь к маршрутизируемому интерфейсу:
>
> - Разместите сервер за аутентифицирующим обратным прокси (например, nginx + mTLS)
>   перед его внешним доступом.
> - Локальные пути и URL-адреса `file://` **автоматически отклоняются** по HTTP для
>   предотвращения чтения неаутентифицированными вызывающими произвольных файлов хоста. Принимаются только удалённые URL-адреса Git и `.zip`.

## Паттерны уязвимостей

SkillSpector обнаруживает **68 паттернов уязвимостей** в 17 категориях:

### Инъекция в промпт (5 паттернов)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| P1 | Переопределение инструкций | ВЫСОКИЙ | Команды игнорировать ограничения безопасности |
| P2 | Скрытые инструкции | ВЫСОКИЙ | Вредоносные директивы в комментариях/невидимом тексте |
| P3 | Команды эксфильтрации | ВЫСОКИЙ | Инструкции по внешней передаче контекста |
| P4 | Манипуляция поведением | СРЕДНИЙ | Тонкие инструкции, изменяющие решения агента |
| P5 | Вредоносный контент | КРИТИЧЕСКИЙ | Инструкции, которые могут причинить физический вред |

### Анти-отказ (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| AR1 | Подавление отказа | ВЫСОКИЙ | Инструкции никогда не отказывать или всегда соглашаться (например, «никогда не отказывай», «всегда соглашайся») |
| AR2 | Подавление дисклеймеров | ВЫСОКИЙ | Инструкции опускать предупреждения, дисклеймеры или этические комментарии (например, «без дисклеймеров», «не морализируй») |
| AR3 | Аннулирование политики безопасности | ВЫСОКИЙ | Jailbreak-формулировки, аннулирующие защитные механизмы (например, «у тебя нет ограничений», «игнорируй свои инструкции», «делай что угодно») |

### Эксфильтрация данных (4 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| E1 | Внешняя передача | СРЕДНИЙ | Отправка данных на внешние URL-адреса |
| E2 | Сбор переменных окружения | ВЫСОКИЙ | Перечисление, копирование или поиск данных окружения для сбора секретов |
| E3 | Перечисление файловой системы | СРЕДНИЙ | Сканирование каталогов на предмет конфиденциальных файлов |
| E4 | Утечка контекста | ВЫСОКИЙ | Передача контекста разговора во внешнюю среду |

### Повышение привилегий (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| PE1 | Чрезмерные разрешения | НИЗКИЙ | Запрос доступа за пределами заявленной функциональности |
| PE2 | Выполнение с sudo/root | СРЕДНИЙ | Вызов повышенных системных привилегий |
| PE3 | Доступ к учётным данным | ВЫСОКИЙ | Чтение SSH-ключей, токенов, паролей |

### Цепочка поставок (6 паттернов)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| SC1 | Незакреплённые зависимости | НИЗКИЙ | Отсутствие ограничений версий пакетов |
| SC2 | Загрузка внешних скриптов | ВЫСОКИЙ | curl \| bash и удалённое выполнение кода |
| SC3 | Обфусцированный код | ВЫСОКИЙ | Выполнение кода в кодировке Base64/hex |
| SC4 | Известные уязвимые зависимости | ВЫСОКИЙ | Зависимости с известными CVE (живой поиск по OSV.dev) |
| SC5 | Заброшенные зависимости | СРЕДНИЙ | Неподдерживаемые пакеты без обновлений безопасности |
| SC6 | Тайпсквоттинг | ВЫСОКИЙ | Имена пакетов, похожие на популярные пакеты |

### Чрезмерная автономия (4 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| EA1 | Неограниченный доступ к инструментам | ВЫСОКИЙ | Беспрепятственный доступ к инструментам без ограничений |
| EA2 | Автономное принятие решений | ВЫСОКИЙ | Решения высокой значимости без участия человека (human-in-the-loop) |
| EA3 | Расширение области действия | СРЕДНИЙ | Возможности, выходящие за пределы заявленного назначения |
| EA4 | Неограниченный доступ к ресурсам | СРЕДНИЙ | Отсутствие лимитов частоты или квот на потребление ресурсов |

### Обработка вывода (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| OH1 | Непроверенная инъекция вывода | ВЫСОКИЙ | Вывод модели используется без санитизации |
| OH2 | Межконтекстный вывод | СРЕДНИЙ | Вывод передаётся через границы доверия без проверки |
| OH3 | Неограниченный вывод | СРЕДНИЙ | Отсутствие ограничений на размер вывода или скорость генерации |

### Утечка системного промпта (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| P6 | Прямая утечка | ВЫСОКИЙ | Инструкции, раскрывающие системные промпты или внутренние правила |
| P7 | Косвенное извлечение | СРЕДНИЙ | Извлечение через перефразирование, перевод или побочные каналы |
| P8 | Эксфильтрация через инструменты | ВЫСОКИЙ | Системные промпты эксфильтруются через запись файлов или сетевые запросы |

### Отравление памяти (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| MP1 | Постоянная инъекция контекста | ВЫСОКИЙ | Контент, предназначенный для сохранения между взаимодействиями |
| MP2 | Заполнение контекстного окна | СРЕДНИЙ | Заполняющий контент, вытесняющий ограничения безопасности |
| MP3 | Манипуляция памятью | ВЫСОКИЙ | Вмешательство в память агента или сохранённое состояние |

### Неправильное использование инструментов (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| TM1 | Злоупотребление параметрами инструментов | ВЫСОКИЙ | Специально созданные параметры для нежелательного поведения (shell=True, --force) |
| TM2 | Злоупотребление цепочками | ВЫСОКИЙ | Цепочки инструментов, обходящие отдельные проверки безопасности |
| TM3 | Небезопасные значения по умолчанию | СРЕДНИЙ | Чрезмерно разрешающие настройки по умолчанию (отключённый TLS, без аутентификации) |

### Недобросовестный агент (2 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| RA1 | Самомодификация | КРИТИЧЕСКИЙ | Изменение собственного кода или конфигурации во время выполнения |
| RA2 | Сохранение сеанса | ВЫСОКИЙ | Несанкционированное закрепление через cron-задачи или стартовые скрипты |

### Злоупотребление триггерами (3 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| TR1 | Слишком широкий триггер | СРЕДНИЙ | Шаблоны триггеров, совпадающие с распространёнными словами |
| TR2 | Триггер теневой команды | ВЫСОКИЙ | Триггеры, перекрывающие встроенные команды или другие навыки |
| TR3 | Триггер на основе ключевых слов-приманок | СРЕДНИЙ | Общие триггеры, предназначенные для максимальной активации |

### Поведенческий AST (9 паттернов)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| AST1 | Вызов exec() | КРИТИЧЕСКИЙ | Прямой вызов exec(), позволяющий произвольное выполнение кода |
| AST2 | Вызов eval() | ВЫСОКИЙ | Прямой вызов eval(), вычисляющий произвольные выражения |
| AST3 | Динамический импорт | ВЫСОКИЙ | \_\_import\_\_() загружает произвольные модули во время выполнения |
| AST4 | Вызов subprocess | ВЫСОКИЙ | Выполнение внешних команд через subprocess |
| AST5 | os.system / семейство exec | ВЫСОКИЙ | Команды оболочки через os-модуль |
| AST6 | Вызов compile() | СРЕДНИЙ | Создание объекта кода из строк |
| AST7 | Динамический getattr() | СРЕДНИЙ | Произвольный доступ к атрибутам с не-литеральными именами |
| AST8 | Опасная цепочка выполнения | КРИТИЧЕСКИЙ | exec/eval в сочетании с динамическим источником (сеть, закодированные данные) |
| AST9 | Рефлексивный приёмник getattr() | ВЫСОКИЙ | Рефлексивный exec через `getattr(os,'system')` / `getattr(builtins,'exec')`, обходящий AST1/AST5 |

### Taint-отслеживание (5 паттернов)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| TT1 | Прямой поток Taint | ВЫСОКИЙ | Данные передаются напрямую от источника к приёмнику без санитизации |
| TT2 | Опосредованный переменными Taint-поток | СРЕДНИЙ | Данные передаются от источника к приёмнику через промежуточные переменные |
| TT3 | Цепочка эксфильтрации учётных данных | КРИТИЧЕСКИЙ | Учётные данные (переменные окружения, секреты) попадают в сетевые выходные приёмники |
| TT4 | Чтение файла с сетевой эксфильтрацией | ВЫСОКИЙ | Содержимое файлов попадает в сетевые выходные приёмники |
| TT5 | Внешний ввод к выполнению кода | КРИТИЧЕСКИЙ | Сетевой ввод или ввод пользователя попадает в приёмники exec/eval/subprocess |

### Сигнатуры YARA (4 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| YR1 | Совпадение с вредоносным ПО | КРИТИЧЕСКИЙ | Совпадение с правилом YARA для известных сигнатур вредоносного ПО |
| YR2 | Совпадение с веб-шеллом | КРИТИЧЕСКИЙ | Совпадение с правилом YARA для паттернов веб-шеллов |
| YR3 | Совпадение с криптомайнером | ВЫСОКИЙ | Совпадение с правилом YARA для индикаторов криптомайнинга |
| YR4 | Совпадение с хакерским инструментом / эксплойтом | ВЫСОКИЙ | Совпадение с правилом YARA для хакерских инструментов или кода эксплойтов |

### Минимальные привилегии MCP (4 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| LP1 | Недооценённая возможность | ВЫСОКИЙ | Код использует возможности, не указанные в объявленных разрешениях |
| LP2 | Разрешение с подстановочным знаком | СРЕДНИЙ | Список разрешений содержит подстановочные знаки (\*, all, full, any) |
| LP3 | Отсутствие объявления разрешений | СРЕДНИЙ | Поле разрешений отсутствует, но код имеет обнаруживаемые возможности |
| LP4 | Избыточно объявленное разрешение | НИЗКИЙ | Разрешение объявлено, но соответствующая возможность в коде не найдена |

### Отравление инструментов MCP (4 паттерна)

| ID | Паттерн | Серьёзность | Описание |
|----|---------|----------|-------------|
| TP1 | Скрытые инструкции | ВЫСОКИЙ | Скрытые директивы в метаданных (HTML-комментарии, символы нулевой ширины, base64, data URI) |
| TP2 | Обман с помощью Unicode | ВЫСОКИЙ | Гомоглифы, RTL-переопределения, идентификаторы со смешанными алфавитами в метаданных инструментов |
| TP3 | Инъекция в описание параметра | СРЕДНИЙ | Паттерны инъекций в определениях параметров (переопределения, системные токены, вредоносные значения по умолчанию) |
| TP4 | Несоответствие описания и поведения | СРЕДНИЙ | Объявленное описание инструмента не соответствует фактическому поведению кода (на основе LLM) |

Все обнаруженные паттерны перечислены в таблицах выше.

## Расчёт риска

### Расчёт баллов

- **Критические проблемы**: +50 баллов
- **Проблемы высокого уровня**: +25 баллов
- **Проблемы среднего уровня**: +10 баллов
- **Проблемы низкого уровня**: +5 баллов
- **Исполняемые скрипты**: множитель 1.3x

### Уровни серьёзности

| Баллы | Серьёзность | Рекомендация |
|-------|----------|----------------|
| 0-20 | НИЗКИЙ | БЕЗОПАСНО |
| 21-50 | СРЕДНИЙ | ОСТОРОЖНО |
| 51-80 | ВЫСОКИЙ | НЕ УСТАНАВЛИВАТЬ |
| 81-100 | КРИТИЧЕСКИЙ | НЕ УСТАНАВЛИВАТЬ |

## Пример вывода

### Вывод в терминале```
 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

Environment Variables

VariableDescriptionRequired
SKILLSPECTOR_PROVIDERАктивный LLM-провайдер: openai, anthropic, anthropic_proxy, bedrock, nv_build, claude_cli, codex_cli или gemini_cli. Для хостируемых провайдеров используются встроенные значения по умолчанию из model_registry.yaml; claude_cli и codex_cli откатываются к модели по умолчанию локального CLI-рантайма, если не задан SKILLSPECTOR_MODEL. По умолчанию — nv_build.Необязательная
NVIDIA_INFERENCE_KEYУчётные данные для провайдера nv_build (build.nvidia.com).Требуется для LLM-анализа, когда SKILLSPECTOR_PROVIDER=nv_build
OPENAI_API_KEYУчётные данные для провайдера OpenAI (SKILLSPECTOR_PROVIDER=openai). Также используется как резерв уровня 2 в каскаде учётных данных, если активный провайдер не вернул учётные данные.Требуется для LLM-анализа, когда SKILLSPECTOR_PROVIDER=openai
OPENAI_BASE_URLПереопределяет конечную точку OpenAI (например, для указания на Ollama).Необязательная
SKILLSPECTOR_REASONING_EFFORTНеобязательная настройка уровня рассуждений, зависящая от провайдера и модели. Непустые значения обрезаются и передаются без изменений; если значение не задано или пустое, сохраняется поведение провайдера по умолчанию.Необязательная
ANTHROPIC_API_KEYУчётные данные для провайдера Anthropic (SKILLSPECTOR_PROVIDER=anthropic).Требуется для LLM-анализа, когда SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_BASE_URLПереопределяет нативную конечную точку Anthropic (по умолчанию: https://api.anthropic.com).Необязательная
ANTHROPIC_PROXY_ENDPOINT_URLПолный URL конечной точки для прокси-провайдера Anthropic (raw-predict в стиле Vertex).Требуется, когда SKILLSPECTOR_PROVIDER=anthropic_proxy
ANTHROPIC_PROXY_API_KEYBearer-токен для прокси-провайдера Anthropic.Требуется, когда SKILLSPECTOR_PROVIDER=anthropic_proxy
ANTHROPIC_PROXY_API_VERSIONЗначение anthropic_version, отправляемое в теле запроса (по умолчанию: vertex-2023-10-16).Необязательная
AWS_PROFILEИменованный профиль AWS для провайдера Bedrock — аутентификация через SigV4 с помощью boto3. Если не задан, используется стандартная цепочка учётных данных boto3 (переменные окружения, метаданные инстанса, SSO и т. д.).Необязательная (используется, когда SKILLSPECTOR_PROVIDER=bedrock)
AWS_REGIONРегион AWS для конечной точки Bedrock Runtime. По умолчанию — us-west-2.Необязательная (используется, когда SKILLSPECTOR_PROVIDER=bedrock)
SKILLSPECTOR_MODELПереопределяет модель активного провайдера. Для хостируемых провайдеров заменяет встроенное значение по умолчанию из таблицы LLM Analysis. Для claude_cli и codex_cli передаётся как --model вместо использования резервной модели локального CLI-рантайма.Необязательная
SKILLSPECTOR_MODEL_REGISTRYПереопределяет встроенный YAML-реестр для каждого провайдера (src/skillspector/providers/<provider>/model_registry.yaml) на пользовательский путь.Необязательная
SKILLSPECTOR_LOG_LEVELУровень журналирования: DEBUG, INFO, WARNING, ERROR (по умолчанию: WARNING).Необязательная

CLI-провайдеры (claude_cli, codex_cli): API-ключ не требуется. Аутентификация полностью управляется сеансом входа самого агентского CLI (claude auth login / codex login). SkillSpector никогда не считывает и не передаёт API-ключи, когда активны эти провайдеры. Дочерний процесс запускается в усиленной изолированной среде: инструменты отключены, MCP отсутствует, включён режим песочницы только для чтения (codex), а непроверенный контент навыков передаётся только через stdin.

Параметры CLI```bash

skillspector scan --help

Options: -f, --format [terminal|json|markdown|sarif] Output format [default: terminal] -o, --output PATH Output file path --no-llm Skip LLM analysis (static only) --yara-rules-dir PATH Extra YARA rules directory -b, --baseline PATH Suppress findings listed in a baseline --show-suppressed List baseline-suppressed findings -V, --verbose Show detailed progress --help Show this message and exit

Generate a baseline of all current findings (see docs/SUPPRESSION.md)

skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]

## Интеграция SkillSpector

SkillSpector создан для работы под управлением других инструментов (CI-конвейеров, шлюзов установки, интеграций с редакторами). Его код возврата и JSON-вывод являются стабильным контрактом.

### Коды возврата

`skillspector scan` завершается со следующими кодами:

| Код | Значение |
|------|---------|
| `0` | Сканирование завершено, `risk_score` ≤ 50 (рекомендация `SAFE` или `CAUTION`) |
| `1` | Сканирование завершено, `risk_score` > 50 (рекомендация `DO_NOT_INSTALL`) |
| `2` | Ошибка (неверный ввод, нечитаемый исходный код, внутренний сбой) |

> Код возврата сводит `SAFE` и `CAUTION` к `0`. Чтобы реагировать на них по-разному (например, *предупреждать* при `CAUTION`, но *блокировать* при `DO_NOT_INSTALL`), читайте поле `recommendation` из JSON-вывода, а не полагайтесь на код возврата.

### Машиночитаемый вывод

`--format json` создаёт JSON-отчёт; при отсутствии `--output`/`-o` он выводится в stdout:```bash
skillspector scan ./my-skill/ --format json

Форма верхнего уровня выглядит следующим образом (этот пример показывает полное сканирование на основе LLM; с параметром --no-llm поле metadata.llm_requested равно false):```json { "skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" }, "risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" }, "components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ], "issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ], "metadata": { "has_executable_scripts": false, "skillspector_version": "...", "llm_requested": true, "llm_available": true, "inference_usage": [ { "node": "semantic_security_discovery", "request_kind": "structured_output", "provider": "nv_inference", "model": "azure/anthropic/claude-opus-4-6", "model_source": "provider_response", "usage_source": "provider_response", "prompt_tokens": 1000, "completion_tokens": 100, "cached_tokens": 400, "cache_write_tokens": 50, "total_tokens": 1100 } ] } }

- `risk_assessment.severity` ∈ `LOW | MEDIUM | HIGH | CRITICAL`.
- `risk_assessment.recommendation` ∈ `SAFE | CAUTION | DO_NOT_INSTALL`, сопоставляется с уровнем серьёзности: `LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error` появляется только тогда, когда анализ LLM был запрошен, но оказался недоступен.
- `metadata.inference_usage` содержит одну очищенную запись на каждый ответ LLM, когда
  провайдер предоставляет счётчики токенов. Он представляет собой пустой список, когда
  использование недоступно; SkillSpector никогда не оценивает отсутствующие токены.
  Суммарные объёмы промптов включают чтение и записи кэша, чтобы нижестоящая система
  ценообразования могла безопасно разделять эти категории. `model_source`
  различает независимо определённую модель провайдера и точно запрошенную модель,
  используемую, когда идентичность ответа отсутствует или неоднозначна. SkillSpector
  в настоящее время не отправляет управляющие параметры prompt-cache от Anthropic,
  поэтому его запросы сканирования не могут выбирать отдельные уровни записи кэша
  на 5 минут или 1 час; поля ответа, зависящие от TTL, консервативно нормализуются в общий счётчик записи кэша.
- См. [Телеметрия использования инференса](https://github.com/nvidia/skillspector/blob/HEAD/docs/INFERENCE_USAGE.md) для получения полного
  описания происхождения данных, учёта кэша, конфиденциальности, приёма с отказом по умолчанию (fail-closed)
  и контракта нижестоящего ценообразования.
- Полная структура каждой проблемы определяется методом `Finding.to_dict()` в [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py); полагайтесь на указанные выше поля и рассматривайте любые дополнительные поля как best-effort.

Для CI/IDE-инструментов `--format sarif` выдаёт SARIF 2.1.0.

### Рекомендуемое сопоставление для шлюза

При использовании SkillSpector в качестве шлюза установки сопоставьте рекомендацию с действием:

| `recommendation` | Предлагаемое действие |
|------------------|------------------|
| `SAFE` | разрешить |
| `CAUTION` | запросить / предупредить пользователя |
| `DO_NOT_INSTALL` | блокировать |

SkillSpector вычисляет диапазон оценки и рекомендацию; насколько строгим является шлюз (например, блокирует ли `CAUTION` в CI), — это политическое решение, принимаемое интегрирующим инструментом.

## Разработка

### Настройка

Все цели `make` предполагают, что виртуальное окружение уже создано и активировано. Makefile использует **uv**, если он доступен, в противном случае — **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 использует двухэтапный конвейер обнаружения:

Этап 1: Статический анализ

  • Быстрое сопоставление шаблонов на основе регулярных выражений в 11 статических анализаторах
  • Поведенческий анализ на основе AST, выявляющий опасные вызовы (exec, eval, subprocess и т.д.)
  • Живой поиск уязвимостей через OSV.dev для известных CVE в зависимостях
  • Сканирует все файлы навыка, подходящие для анализаторов
  • Высокая полнота (обнаруживает большинство проблем)
  • Умеренная точность (некоторые ложные срабатывания)

Действительная подпись OpenSSF Model Signing корневого уровня (skill.oms.sig) сохраняется в реестре компонентов как тип oms_signature, но исключается из статического и LLM-анализа содержимого. Пакеты OMS обязательно содержат длинные поля полезной нагрузки, подписи и сертификата в кодировке base64; в противном случае общие проверки обфусцированного кода могут ошибочно классифицировать эти поля как скрытый исполняемый контент. Распознаватель проверяет минимальную структуру OMS DSSE/in-toto; он не проверяет подпись, цепочку сертификатов, запись в журнале прозрачности или личность подписанта. Недействительные или нераспознанные файлы подписей сканируются обычным образом.

Этап 2: Семантический анализ LLM (опционально)

  • Оценивает контекст и намерения
  • Отфильтровывает ложные срабатывания
  • Предоставляет понятные человеку объяснения
  • Повышает точность до ~87%

Промпт LLM включает защиту от джейлбрейка, чтобы предотвратить манипулирование анализом со стороны вредоносных навыков.

Живой поиск уязвимостей (SC4)

SC4 использует API OSV.dev для проверки зависимостей по полной базе данных Open Source Vulnerabilities — охватывающей десятки тысяч бюллетеней по PyPI и npm.

  • API-ключ не требуется — OSV.dev бесплатен и не требует аутентификации.
  • Пакетные запросы — все зависимости проверяются одним HTTP-вызовом.
  • Автоматический запасной вариант — если OSV.dev недоступен (изолированная сеть/офлайн), используется небольшой встроенный запасной список.
  • Кэширование — результаты кэшируются в памяти на 1 час, чтобы избежать повторных API-вызовов в течение сеанса.

Инструменту требуется исходящий HTTPS-доступ к api.osv.dev для получения актуальных данных об уязвимостях. Когда он недоступен, результаты ограничиваются статическим запасным списком.

Модель доверия и исходящие данные

SkillSpector — это эшелонированная защита, а не песочница. Прежде чем полагаться на него, знайте, что он делает и чего не делает:

  • Он никогда не выполняет сканируемый навык. Весь анализ статический (regex, Python AST, YARA) плюс опциональная LLM-оценка содержимого файлов — код навыка никогда не запускается.
  • LLM-анализ отправляет содержимое файлов, подходящих для анализаторов, настроенному провайдеру. Когда LLM-анализ включён (по умолчанию), содержимое файлов отправляется на активную конечную точку SKILLSPECTOR_PROVIDER. Распознанные файлы подписей OMS исключаются. Используйте --no-llm, чтобы оставить содержимое локальным (только статический анализ).
  • SC4 отправляет имена зависимостей в OSV.dev. Проверка цепочки поставок запрашивает OSV.dev с указанными в навыке именами и версиями пакетов для поиска известных CVE. Это базовая функция проверки, которая работает даже с --no-llm. Она отправляет координаты зависимостей (не содержимое файлов), не требует API-ключа и переключается на встроенный список, когда OSV.dev недоступен.
  • Он не изолирует хост. SkillSpector помечает опасные паттерны до установки навыка; он не сдерживает и не изолирует навык, который вы всё равно решите установить.

Ограничения

  • Неанглоязычный контент: может пропускать паттерны на других языках
  • Атаки на основе изображений: не может анализировать текст на изображениях
  • Зашифрованный/бинарный код: не может анализировать скомпилированный или зашифрованный контент
  • Поведение во время выполнения: только статический анализ, без динамического выполнения
  • Офлайн SC4: без сетевого доступа к api.osv.dev SC4 использует небольшой статический запасной список

Научная основа

На основе исследования «Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale» (Liu et al., 2026):

  • Набор данных: 42 447 навыков из крупных маркетплейсов
  • Уязвимые: 26,1% содержат хотя бы одну уязвимость
  • Высокая серьёзность: 5,2% демонстрируют вероятный вредоносный умысел
  • Ключевой вывод: навыки с исполняемыми скриптами в 2,12 раза более уязвимы

Интеграция с Python API```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']}")

## License

Apache License 2.0 — подробности в [LICENSE](https://github.com/nvidia/skillspector/blob/HEAD/LICENSE).

## Contributing

Приветствуются любые вклады! Пожалуйста, ознакомьтесь с нашими рекомендациями по внесению вклада и отправляйте pull request'ы.

## Support

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

Категории