Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
SecureAI-Scan — SecureAI-Scan — это CLI-инструмент, который сканирует кодовые базы TypeScript и JavaScript на предмет проблем безопасности, специфичных для приложений на базе ИИ: инъекции в промпты, злоупотребление MCP-инструментами, отравление данных RAG, нарушения доверия агентов и другое. | Kitploit
Инструменты/GitHubGitHub/akanthed/secureai-scan
Статический анализСканеры уязвимостейАнализ КодаDevSecOpsОбнаружение СекретовБезопасность Цепочки ПоставокОбучение и ОбразованиеБезопасность ИИ
GitHubakanthed/secureai-scan

SecureAI-Scan

SecureAI-Scan — это CLI-инструмент, который сканирует кодовые базы TypeScript и JavaScript на предмет проблем безопасности, специфичных для приложений на базе ИИ: инъекции в промпты, злоупотребление MCP-инструментами, отравление данных RAG, нарушения доверия агентов и другое.

1911213 дней назадПроверено Kitploit
Репозиторий
Сайт

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

SecureAI-Scan

npm version npm downloads CI CodeQL OpenSSF Scorecard license Node OWASP

Офлайн-CLI, который сканирует TypeScript, JavaScript и Python на предмет рисков LLM, MCP, Agent Skill и RAG — доказательства потока данных с разрешением импортов, ноль ложных срабатываний по умолчанию, сопоставлено с OWASP LLM/ASI/MCP Top 10.

Большинство сканеров в этой области сопоставляют ключевое слово по шаблону и называют это находкой. SecureAI-Scan прослеживает фактический путь источник → поток → приёмник через реальный код с разрешением импортов — и сканирование по умолчанию показывает только то, что может доказать. Без аккаунта, без загрузки в облако, ничего не покидает вашу машину.

Охватывает официальные OWASP Top 10 для LLM-приложений 2026, Top 10 для агентных приложений (2026) и MCP Top 10 с первой недели запуска.

Начало работы за 30 секунд```bash

npx --yes [email protected] scan .

root@kitploit:~
Нет необходимости в аккаунте, облачной загрузке, интерпретаторе Python или настройке. TypeScript, JavaScript, Python, MCP-конфигурации и пакеты Agent Skill определяются автоматически.

**Измеренный кандидат в релиз `0.9.0`:** 136/136 тестов · 88.08% покрытие операторов · 12 676 файлов в 9 публичных репозиториях · 0 новых отпечатков уровня по умолчанию относительно проверенного базового уровня. [Доказательства](https://github.com/akanthed/secureai-scan/blob/main/docs/benchmarks/v0.9.0.json) · [методология и ограничения](https://github.com/akanthed/secureai-scan/blob/main/docs/ReleaseAssurance.md)```
  ▌ HIGH  AI001  Prompt injection via user input
    PROVEN  LLM01:2026 Prompt Injection

    source src/chat.ts:8   request data `req.body.input`
    flow   src/chat.ts:13  passed as `systemPrompt`
    sink   src/chat.ts:10  openai.chat.completions.create — system role (OpenAI)

    fix    Keep system prompts static; pass user input as a user-role message.

Это для вас? SecureAI-Scan намеренно ограничен рисками LLM, MCP и RAG/агентов — промпт-инъекциями, отравлением инструментов, небезопасной обработкой вывода, контролем доступа к векторным хранилищам, отравлением навыков агентов. Это не универсальный SAST- или секрет-сканер, и он не пытается им быть; известный вредоносный пакет без полезной нагрузки в форме LLM (например, жёстко заданный адрес эксфильтрации в вызове email API) обнаруживается офлайн-списком рекомендаций (DEP003), а не правилом-паттерном. Если ваша кодовая база взаимодействует с LLM, MCP-сервером, векторным хранилищем или поставляет Agent Skills — этот инструмент создан для вас.

Новое: статическое сканирование конфигурации для LiteLLM Proxy (config.yaml) — жёстко заданные секреты, открытые текстом конечные точки провайдера, отсутствующие защитные механизмы. См. Правила (LLC001–LLC003).

Содержание

  • Почему этот сканер отличается
  • С чем его сравнить
  • Начало работы за 30 секунд
  • Посмотрите, как он работает
  • Команды
  • GitHub Action
  • Pre-commit hook
  • Правила
  • Архитектура
  • MCP-сервер (используйте его из Claude)
  • Claude Skill
  • Гарантии доверия и релиза
  • Контракт точности
  • Тестирование и бенчмаркинг
  • Дорожная карта
  • Вклад в проект

Почему этот сканер отличается

  • Уровни доказательности, а не шум. Каждая находка — proven (прослеженный поток данных или установленный факт из конфига), likely (разрешённый приёмник, один эвристический шаг) или heuristic. Стандартное сканирование показывает только proven + likely. Эвристики включаются опционально через --paranoid.
  • Детекция с разрешением импортов. Вызов считается «LLM-вызовом», только если он разрешается в реальный импорт SDK (openai, @anthropic-ai/sdk, ai, @google/genai, LangChain, Bedrock, …). Ваш клиент Google Maps больше никогда не будет помечен как LLM.
  • Ограничен по точности и протестирован на реальных репозиториях. Тестовый набор утверждает, что каждая уязвимая фикстура срабатывает и каждая безопасная фикстура остаётся чистой — ложное срабатывание на безопасном корпусе ломает сборку. Кроме того, npm run regression сканирует реальные публичные репозитории (OpenAI/Anthropic/Vercel AI SDKs, официальные MCP-серверы, LlamaIndex) против зафиксированного, вручную проверенного базового уровня и падает при любой новой находке proven/likely. См. Тестирование и бенчмаркинг для фактических цифр до/после, или Что мы нашли при сканировании реальных репозиториев для истории за ними — 6/6 уровень обнаружения на размеченном корпусе вредоносных навыков, и почему мы не называем llama_index «уязвимым» из-за честной находки на уровне библиотеки. Обсуждение →
  • SARIF для GitHub code scanning. --output report.sarif размещает находки прямо в pull request и во вкладке Security.
  • AI-BOM. secureai-scan bom . строит инвентарь на основе синтаксиса: SDK, ID моделей, векторные хранилища, агентные фреймворки и MCP-серверы, сопоставленные с потребностями документации OWASP LLM Top 10 / EU AI Act.
  • Сканирование MCP-конфигурации. Разбирает .mcp.json, claude_desktop_config.json, .cursor/mcp.json: незакреплённые npx -y серверы, встроенные секреты, HTTP-транспорты открытым текстом.
  • Детекция отравления MCP-инструментов. Ловит паттерн, стоящий за rug-pull WhatsApp MCP и бэкдором postmark-mcp — невидимый Unicode, фразы инъекций, направленные на агента, и затенение между инструментами в именах/описаниях, статически, до того как вы запустите сервер.
  • Детекция инъекций команд в MCP. Помечает command/args stdio-транспорта MCP, построенные из данных запроса — паттерн, стоящий за раскрытием RCE в MCP STDIO 2026 года.
  • Детекция отравления Agent Skills. Те же проверки невидимого Unicode, фраз инъекций и затенения применяются к файлам SKILL.md — Agent Skills загружаются в контекст целиком, поэтому отравленный навык — это отравленное описание инструмента под другим именем.
  • Устойчивое к обходу сканирование навыков. Пакеты навыков сканируются как каталоги, а не только их SKILL.md, и каждая проверка содержимого выполняется против деобфусцированных вариантов текста. Это нацелено на опубликованные техники — гомоглифы, разбиение нулевой ширины, полезные нагрузки в .git/ или build/, эксфильтрация, скрытая в файле *.test.ts, — которые обошли >90% из девяти сканеров, исследованных в Cloak and Detonate (arXiv:2607.02357). См. Устойчивость к обходу.
  • Рекомендации по известным уязвимым и вредоносным пакетам с учётом версий. Проверяет каждую зависимость и каждый пакет, запускаемый через MCP, против встроенного снимка рекомендаций — вручную подобранный список задокументированных бэкдоров в дикой природе, плюс рекомендации OSV уровня HIGH/CRITICAL для списка отслеживания LLM/MCP/RAG-пакетов, перегенерируемые scripts/sync-advisories.js. Работает офлайн при каждом сканировании, без необходимости флага. CVE срабатывает только когда ваша закреплённая версия доказуемо находится в затронутом диапазоне; задокументированный вредоносный пакет срабатывает даже при неоднозначном диапазоне, потому что установка бэкдора необратима.
  • Локально в первую очередь. Ничего не покидает вашу машину.

С чем его сравнить

SecureAI-Scan не заменяет универсальный SAST-инструмент или сканер контейнеров/IaC — запускайте его вместе с ними, а не вместо. Он создан специально для поверхности атаки LLM/MCP/RAG и делает акцент на доказательности потока данных, а не на плоских находках по ключевым словам.

SecureAI-ScanSemgrep (OSS rules)TrivyGitHub Advanced Security
Промпт-инъекция (источник→приёмник прослежен)✅ поток данных с разрешением импортов⚠️ только правила-паттерны, поддерживаются сообществом❌⚠️ CodeQL может, но нет набора правил для ИИ
Отравление MCP-инструментов / риск конфигурации✅ MCP007–010, сканер конфигурации❌❌❌
Отравление Agent Skills (SKILL.md)✅ устойчиво к обходу, с учётом пакетов❌❌❌
Неправильная настройка RAG / векторных хранилищ✅ VEC001–004❌❌❌
Рекомендации по известным вредоносным ИИ-пакетам✅ DEP003, офлайн, с учётом версий❌⚠️ общий поток CVE, не для ИИ⚠️ Dependabot, общий поток CVE
Общий SAST (SQLi, XSS, path traversal)❌ вне области действия по дизайну✅❌✅
Сканирование контейнеров / IaC❌❌✅⚠️ через CodeQL/Actions
Уровни доказательности (proven/likely/heuristic)✅❌ находки плоские❌⚠️ CodeQL имеет некоторые, не настроены под ИИ
Вывод SARIF (GitHub code scanning)✅✅✅нативный
Работает офлайн, без аккаунта✅✅ (OSS rules)✅❌ требует GitHub

Если вы уже используете Semgrep или GHAS, оставьте их — добавьте SecureAI-Scan для той поверхности риска, которую они вообще не моделируют.

Предпочитаете сначала задать вопросы? Попробуйте бесплатного AI-консультанта по безопасности SecureAI-Scan на ChatGPT.

Собираетесь запустить MCP-сервер, найденный на GitHub или в Twitter? Сначала вставьте его описание инструмента в MCP X-Ray — он проверит его на скрытый Unicode, внедрённые инструкции и известные вредоносные пакеты в вашем браузере, без установки.

Посмотрите, как он работает

secureai-scan scan . от начала до конца, реальный вывод на реальном (маленьком, намеренно уязвимом) файле — исходник:

Запись терминала: secureai-scan scan . находит прослеженную уязвимость промпт-инъекции

Формы атак, которые сканер прослеживает от начала до конца:

Поток данных отравления MCP-инструментовПоток данных инъекции в контекст RAG
Трассировка атаки MCPТрассировка отравления RAG

Команды

Та, что нужна вам в 95% случаев:```bash secureai-scan scan .

root@kitploit:~
Все остальное доступно, когда понадобится. `secureai-scan scan . --help` показывает всё это в терминале, сгруппированным так же:

**Повседневное использование**

| Флаг | Что делает |
|------|---------------|
| *(нет)* | результаты `proven` + `likely` — по умолчанию, флаги не нужны |
| `--paranoid` | также включает результаты уровня `heuristic` |
| `-s, --severity <уровень>` | показывать только результаты на уровне `low`\|`medium`\|`high`\|`critical` и выше |
| `--output <файл>` | записать полный отчёт — `.sarif` (code scanning GitHub), `.json`, `.md` или `.html` |

**Область применения: какие правила запускать**

| Флаг | Что делает |
|------|---------------|
| `-r, --rules <список>` | запускать только эти ID правил, например `AI001,MCP007` |
| `--only-ai` / `--only-mcp` / `--only-vec` / `--only-skl` | запускать только одну категорию правил |
| `--check-dependencies` | также проверять `package.json`/`requirements.txt` по реестрам npm/PyPI на опечатки и выдуманные пакеты (`DEP001`/`DEP002`). Автоматически включается, если выбрать эти правила напрямую через `-r` — не нужно помнить о передаче обоих флагов. Не требуется для `DEP003` (заведомо вредоносные пакеты), который всегда работает офлайн |

**CI / рабочий процесс**

| Флаг | Что делает |
|------|---------------|
| `--fail-on <серьёзность>` | выход с кодом `1`, если существуют результаты на этом уровне серьёзности и выше |
| `--baseline <файл>` | отслеживать только новые/изменённые проблемы относительно сохранённого базового уровня |
| `--policy <файл>` | загрузить пороги, пропускаемые пути и заблокированные правила из `.secureai-policy.json` (определяется автоматически, если присутствует — `secureai-scan init` создаёт такой файл) |

**Расширенные возможности**

| Флаг | Что делает |
|------|---------------|
| `--min-confidence <0-1>` | более точный, чем `--paranoid`: скрывать результаты ниже точного порога уверенности (`0.9` proven / `0.65` likely / `0.35` heuristic) |
| `--limit <n>` | максимальное количество групп правил, отображаемых в терминале (по умолчанию `10`) — полные детали всегда попадают в `--output` |
| `--debug` | выводить каждый просканированный файл и какие правила выполнялись |

**Сканируйте перед установкой — без клонирования, без настройки:**```bash
secureai-scan skill anthropics/skills          # a GitHub "owner/repo" shorthand
secureai-scan skill https://github.com/…       # or a full git URL
secureai-scan skill ./some/local/skill-dir     # or a local path
secureai-scan mcp some-mcp-server-package      # a bare npm package name
secureai-scan mcp owner/mcp-server-repo        # or git, same as `skill`

skill и mcp загружают цель и сканируют её, после чего удаляют загруженную копию (--keep, чтобы вместо этого изучить её). Ничто из загруженного никогда не выполняется: npm-цель загружается с помощью npm pack — только tarball, без install, без скриптов жизненного цикла — а git-цель представляет собой обычный git clone --depth 1. Это самый важный момент: до того, как навык попадёт в ~/.claude/skills/ или сервер — в .mcp.json, а не после.

Другие команды:```bash secureai-scan bom . --output AI_BOM.md # AI Bill of Materials secureai-scan explain AI001 # why + exploit + fix example, for any rule secureai-scan threat-model . # THREAT_MODEL.md with the OWASP coverage matrix — example: docs/examples/THREAT_MODEL.example.md secureai-scan init # policy file + CI workflow, one-time setup

root@kitploit:~
Подавить проверенное замечание в коде:```ts
// secureai-ignore AI001: reviewed, input sanitized via allowlist

GitHub Action```yaml

name: SecureAI-Scan on: [pull_request] permissions: contents: read security-events: write jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: akanthed/[email protected] with: scanner-version: 0.10.0 fail-on: high

root@kitploit:~
Находки отображаются в виде встроенных аннотаций в PR и на вкладке Security репозитория. (`secureai-scan init` генерирует эквивалентный workflow с использованием CLI напрямую.)

Сканирование чистое? Добавьте бейдж в свой собственный README:```md
[![secureai-scan](https://img.shields.io/badge/secureai--scan-passing-brightgreen)](https://github.com/akanthed/SecureAI-Scan)

Pre-commit hook

Предпочитаете выявлять находки до того, как они будут отправлены? Добавьте этот репозиторий как источник хука pre-commit вместо GitHub Action или вместе с ним:```yaml repos:

  • repo: https://github.com/akanthed/SecureAI-Scan rev: v0.10.0 hooks:
    • id: secureai-scan
root@kitploit:~
The hook scans the whole project on every commit (not just changed files — a dataflow trace into file A can depend on file B, which a partial scan would miss) and blocks the commit on `high`+ severity findings by default. Override the threshold in your own config:```yaml
      - id: secureai-scan
        args: ["--fail-on", "critical"]

Правила

42 правила, сопоставленные с официальным OWASP Top 10 для LLM-приложений (2026) — а также, где применимо, с OWASP Top 10 для агентных приложений (2026, ASI), OWASP MCP Top 10 (2025) и статьёй EU AI Act. См. версионированное покрытие и ограничения 2026; threat-model выводит матрицу для каждого сканируемого проекта.

ПравилоЧто оно доказываетOWASP
AI001Пользовательский ввод попадает в системный/разработческий промпт (прослеженный путь от источника к приёмнику, включая границы функций/файлов)LLM01
AI002Содержимое промпта или секреты записываются в логи (в файлах, использующих LLM SDK)LLM02
AI003Вызов LLM в обработчике запроса без проверки аутентификации перед нимLLM06
AI004Весь объект пользователя/сессии сериализуется в промпт (выбор отдельных полей не помечается)LLM02
AI005Вывод LLM достигает приёмников eval/exec/SQL/HTMLLLM10
AI006Высокорисковые инструменты (delete, pay, deploy, …) доступны без шлюза одобренияLLM03
AI007Извлечённый RAG-контент интерполируется в привилегированные промптыLLM01
AI008Секреты, встроенные в текст системного промптаLLM08
AI009Неограниченный пользовательский ввод / отсутствие лимитов токеновLLM06
AI010Полученный извне контент попадает в промптыLLM01
AI011Вывод агента повышается до системной роли в последующих вызовахLLM03
AI012Вывод LLM разбирается без проверки схемыLLM10
MCP001Метаданные MCP-инструмента достигают системного промпта без валидацииLLM01
MCP002URL MCP-сервера формируется из пользовательского вводаLLM04
MCP003Результаты MCP-инструмента повышаются до системной ролиLLM10
MCP004MCP-сервер запускается как незакреплённый пакет npx -yLLM04
MCP005Секрет, встроенный в закоммиченную MCP-конфигурациюLLM02
MCP006MCP-сервер по незашифрованному HTTPLLM04
MCP007Невидимый/двунаправленный Unicode, скрытый в именах или описаниях MCP-инструментовLLM01 · MCP03
MCP008Фразы инъекций, направляющих агента, в описаниях MCP-инструментовLLM01 · MCP03
MCP009Описание инструмента, перенаправляющее вызовы на другой инструмент (затенение)

secureai-scan explain <RULE_ID> предоставляет описание эксплуатации и пример кода до/после для любого правила.

Архитектура

Три независимые поверхности сканирования питают один объединённый список находок с дедупликацией:``` ┌─────────────────────┐ *.ts / *.js ───▶ │ ts-morph AST rules │───┐ │ (import-resolved │ │ │ sinks + dataflow) │ │ └─────────────────────┘ │ │ ┌─────────────────────┐ │ ┌──────────────┐ ┌─────────────────┐ *.py ───▶ │ tree-sitter AST + │───┼───▶ │ scan.ts │───▶ │ evidence filter │ │ local taint flow │ │ │ merge/dedupe│ │ → confidence │ └─────────────────────┘ │ │ + suppress │ │ → severity │ │ │ (// secure- │ │ → baseline diff │ .mcp.json, ┌─────────────────────┐ │ │ ai-ignore) │ │ → report │ SKILL.md ───▶ │ Config/bundle scan │──┘ └──────────────┘ └─────────────────┘ │ (off-disk, evasion- │ │ │ resistant) │ ▼ └─────────────────────┘ terminal · sarif · json · md · html

package.json, requirements.txt ─▶ dependency-guard.ts (advisories.ts, offline, version-aware)

root@kitploit:~
Каждое правило AST вызывает функцию «LLM-вызовом» только в том случае, если она через реальные импорты разрешается в известный SDK — никогда только по совпадению имени. Полную разбивку каждой поверхности см. в [`docs/Architecture.md`](https://github.com/akanthed/secureai-scan/blob/main/docs/Architecture.md), а о том, как работает контракт уровней доказательств, — в [`docs/DetectionEngine.md`](https://github.com/akanthed/secureai-scan/blob/main/docs/DetectionEngine.md).

## MCP-сервер (используйте его из Claude)

Пакет поставляется с MCP-сервером, предоставляющим `scan_repository`, `explain_rule`, `generate_bom` и `scan_untrusted_target` (получение и сканирование навыка или MCP-сервера, прежде чем Claude порекомендует его установить — то же поведение «получение без выполнения», что и у CLI-команд `skill`/`mcp`):```json
{
  "mcpServers": {
    "secureai-scan": {
      "command": "node",
      "args": ["/path/to/secureai-scan/mcp-server/index.js"]
    }
  }
}

Claude Skill

Для пользователей Claude Code / Claude.ai, skills/secureai-scan/SKILL.md обучает Claude, когда запускать сканирование (при проверке кода AI/LLM или при проверке MCP-сервера/Agent Skill перед его установкой) и как читать результаты — в отличие от MCP-сервера выше, здесь не нужен отдельный процесс. Скопируйте каталог skills/secureai-scan/ в свой .claude/skills/, чтобы использовать его.

Устойчивость к обходу

В июле 2026 года два публичных исследования показали, что сканеры Agent Skill тривиально обходятся.

Cloak and Detonate (Ji, Xu, Li, Gao, Wei, Wang & Cheung — HKUST, arXiv:2607.02357) провели состязательное исследование против девяти опубликованных сканеров навыков, используя 1 613 вредоносных навыков из реального мира. Два семейства атак, оба из которых сохраняют полезную нагрузку в точности:

  • Reify — переписывает байты, на которые срабатывает правило, в то время как агент всё равно восстанавливает оригинал во время выполнения. >80% обход большинства статических сканеров.
  • Disperse / SFS packing — перемещает полезную нагрузку за пределы области действия правила: в каталог, который сканер пропускает, за переименованным расширением, или архивирует и кодирует её в .git/, с безобидным прикрытием SKILL.md, который пересобирает её при первом запуске. ≥90% обход на каждом протестированном сканере, ≥96% на большинстве. У одного гибридного сканера уровень обнаружения упал с ~99% до ~10%.

Отдельно Gecko Security (VentureBeat) разместили полезную нагрузку в файле *.test.ts. Каждый публичный сканер пропустил его — но Jest и Vitest автоматически обнаруживают и выполняют эти файлы при следующем npm test.

SecureAI-Scan обрабатывает каждую опубликованную технику. Каждой строке ниже соответствует тест в test/deobfuscate.test.js или фикстура в test-fixtures/vulnerable/skills/:

Техника (название из статьи)ПримерКак обрабатывается
Вставка нулевой шириныIgn‍ore all pre‍vious…Текст сопоставляется с вариантами без невидимых символов
Схожие глифысurl (кириллическая с)Свёртка гомоглифов в ASCII перед сопоставлением
Смена регистраEvAlВсе шаблоны содержимого нечувствительны к регистру
Склейка переменных'cu' + 'rl'Смежные строковые литералы объединяются перед сопоставлением
Разбиение по строкамev⏎al(x)Разрывы строк внутри слова объединяются как дополнительный вариант
Извлечение по файламполезная нагрузка во вспомогательном файлеСканируется весь пакет, а не только SKILL.md
Перемещение каталогаscripts/x.sh → build/x.shНет списка пропускаемых каталогов внутри пакета
Переименование расширенияx.sh → x.txtФайлы сканируются по содержимому, а не по расширению
Дополнение размерадополнение сверх лимита сканераЧрезмерно большие файлы читаются с начала, никогда не пропускаются
SFS packingполезная нагрузка в .git/skillpack.datЛюбой не-git файл в .git/ пакета помечается как proven (SKL004)
Размещение в тестовых файлахполезная нагрузка в *.test.tsСканирование пакета намеренно не понижает тестовые пути (SKL005)

Это не ослабляет контракт точности

Деобфускация обычно является риском для точности — больше совпадений, больше шума. Здесь логика инвертирована: совпадение, которое появляется только после деобфускации, повышается до proven, а не понижается. Обычная документация не содержит соединителя нулевой ширины внутри «ignore previous instructions» и кириллической с внутри curl. Само сокрытие является утвердительным доказательством намерения.

Сравнение проводится с набором сырых совпадений, а не просто с вопросом «совпал ли сырой текст вообще» — иначе атакующий мог бы замаскировать сигнал, оставив одну безобидную фразу в открытом виде.

Два новых правила пакета срабатывают только на конъюнкции, никогда на отдельное ключевое слово:

  • SKL004 требует непрозрачный блоб и директиву распаковки, которая ссылается на этот блоб по имени — упоминание tar -x в README рядом с несвязанным бинарным ресурсом недостаточно. Настоящие архивы (gzip/zip/png/pdf/wasm — проверяются по магическим байтам, а не по расширению) вообще никогда не являются «непрозрачными», как бы они ни были сжаты.
  • SKL005 требует конкретный сигнал учётных данных — путь (~/.aws/credentials, а не слово «token») или массовое перечисление переменных окружения (os.environ.items(), а не os.environ["API_KEY"]) — и исходящий трафик на жёстко заданный нелокальный хост, в пределах 25 строк друг от друга в одном файле, или удалённую загрузку, которая выполняется после переназначения через одно или несколько переименований. Хелпер публикации, который читает ~/.npmrc в одной функции и вызывает реестр сорока строками позже, остаётся чистым, а чтение одной именованной переменной окружения для вызова API никогда не помечается — обе формы закреплены как безопасные фикстуры.

Проверено на двух реальных корпусах, а не только на фикстурах, написанных нами самими: 0 находок во всех 18 реальных пакетах навыков в anthropics/skills и во всех 14 в vercel/ai, и 6/6 правильных на размеченном оценочном корпусе cisco-ai-defense/skill-scanner (20 навыков, каждый с вердиктом _expected.json) с нулевым количеством ложных срабатываний на всём, что помечено как безопасное. См. Тестирование и бенчмаркинг.

Чем это не является

Честное ограничение: вывод статьи состоит в том, что детонация во время выполнения превосходит статический анализ, и это верно. Адаптивный противник, знающий эти правила, может написать преобразование, которое они не покрывают. Что здесь меняется — это стоимость обхода: опубликованные, ныне циркулирующие техники больше не работают, а обфускация, необходимая для их преодоления, теперь сама повышает серьёзность находки. Статическое сканирование — это фильтр, а не граница безопасности. Относитесь к непроверенному навыку как к непроверенному коду, независимо от того, что говорит любой сканер.

Доверие и гарантии выпуска

  • CI запускается на Linux, Windows и macOS на поддерживаемых версиях Node.
  • CodeQL, аудит производственных зависимостей, OpenSSF Scorecard, Dependabot и собственное блокирующее самосканирование этого сканера обеспечивают независимые проверки.
  • Каждая ручная публикация npm запускает тесты, минимальные пороги покрытия, проверенный шлюз регрессии на реальных репозиториях и проверку tarball через prepublishOnly.
  • GitHub Actions не получает пароль или токен npm и не может опубликовать пакет.
  • Гарантии выпуска, управление с одним мейнтейнером, сообщение об уязвимостях и версионированные свидетельства бенчмарков являются публичными.

Это проект с одним мейнтейнером, без контрактного SLA или независимой сертификации. Указанные выше меры контроля снижают риск; они не превращают статическое сканирование в доказательство безопасности.

Контракт точности

Ложные срабатывания убивают сканеры. Механизм правил SecureAI-Scan следует трём жёстким правилам:

  1. Стоки разрешаются через импорты. Если идентификатор разрешается в модуль, который не является LLM SDK, это определённо не вызов LLM — независимо от его названия.
  2. Свидетельства помечаются, а не смешиваются. Отслеженный поток данных и совпадение по близости слов — не одно и то же, поэтому они никогда не делят один уровень.
  3. Корпус безопасных образцов блокирует каждый выпуск. test-fixtures/safe/ содержит шаблоны, которые раньше вызывали ложные срабатывания (редактированные полезные нагрузки PII, клиенты Google Maps, ключи API из переменных окружения рядом с LLM-клиентами, обычное логирование ответов, поля метаданных OAuth, chunks потоковых ответов, художественный/повествовательный текст промптов). Любая находка там приводит к провалу набора тестов.

Тестирование и бенчмаркинг

Три уровня, потому что одного недостаточно, чтобы доверять заявлениям сканера — точность и полнота — это разные режимы отказа, и проверяются оба.

1. Корпус фикстур — точность + полнота, запускается при каждой сборке.```bash npm test

root@kitploit:~
[`test-fixtures/vulnerable/`](https://github.com/akanthed/secureai-scan/blob/main/test-fixtures/vulnerable) и [`test-fixtures/safe/`](https://github.com/akanthed/secureai-scan/blob/main/test-fixtures/safe) сканируются вместе: каждый уязвимый фикстур должен срабатывать на ожидаемое правило с доказательством `proven`/`likely` (полнота), каждый безопасный фикстур должен давать **ноль** результатов `proven`/`likely` (точность). Быстро и детерминированно — но это лишь доказывает, что сканер ведёт себя корректно на коде, написанном специально для его тестирования.

**2. Регрессионный бенчмарк на реальных проектах — против публичных репозиториев, которые мы не писали.**```bash
npm run regression                          # scan the full curated repo set
npm run regression -- --fresh               # re-clone everything first
npm run regression -- openai-node           # scan just one repo by name
npm run regression -- --update-baseline     # accept the current findings

scripts/regression-scan.js клонирует подобранный, разнообразный набор реальных публичных репозиториев (OpenAI/Anthropic/Vercel AI SDK, официальные MCP-серверы и TypeScript SDK, LlamaIndex, а также anthropics/skills и cisco-ai-defense/skill-scanner для покрытия skill-бандлов — охватывая TS и Python, примеры кода потребителей SDK и исходники авторов SDK) и сканирует каждый из них с помощью собранного CLI.

Он завершается с ненулевым кодом при любом proven/likely срабатывании, отсутствующем в test/regression-baseline.json — вручную проверенной записи срабатываний, уже сверенных с их исходной строкой. Отпечатки имеют формат repo|rule|file, а не номера строк, поэтому обычные изменения в вышестоящих репозиториях не создают шума. Новый отпечаток — это утверждение, которое сканер должен обосновать: если это не реальная проблема, значит, это баг правила, исправленный в корне и закреплённый как новый фикстур в test-fixtures/safe/. Внесение в базовую линию срабатывания, которое вы не прочитали, сводит на нет весь механизм.

Покрытие skill-бандлов выделено отдельной строкой, потому что корпус evals/ из cisco-ai-defense/skill-scanner размечен — каждый из его 20 фикстуров поставляется с вердиктом _expected.json и находится в каталоге, буквально названном malicious/ или safe/, поэтому он служит двойной проверкой полноты, а не только точности: 6/6 вредоносных фикстуров в области действия срабатывают, 0 срабатываний на всём, что помечено как safe, и 0 срабатываний на всех 18 реальных бандлах в anthropics/skills и всех 14 в vercel/ai. (Остальные категории Cisco — SQL-инъекции, обход пути, исчерпание ресурсов, обобщённый eval() аргумента функции, полезная нагрузка, намеренно разбитая на четыре файла — либо выходят за документированную область LLM/MCP/RAG, либо за пределы анализа конъюнкции в пределах одного файла; см. запись в журнале изменений 0.6.0 с конкретным обоснованием по каждой.)

Исторические данные «до/после» из прогона, который привёл к исходным исправлениям точности (срабатывания на уровне доказательств по умолчанию, без --paranoid):

РепозиторийДоПослеЧто было не так
vercel/ai7731Каталоги examples/, корневые tests/ и каталоги в стиле ecosystem-tests/ с дефисами не распознавались как пути с более низким уровнем доверия; chunks (распространённая переменная потокового ответа) рассматривалась как однозначное свидетельство RAG
openai/openai-node470Тот же пробел в определении путей, применённый к собственным examples//ecosystem-tests/ SDK
anthropics/anthropic-sdk-typescript20Тот же пробел в определении путей для корневого каталога tests/
modelcontextprotocol/typescript-sdk30Поля метаданных OAuth в стиле token_endpoint/tokenType помечались как утёкшие секреты
run-llama/llama_index1815Проверка Python помечала любое поле description=, содержащее «system prompt», как proven отравление MCP-инструмента, независимо от контекста. Оставшиеся 15 — это срабатывания VEC001 на собственных обобщённых определениях ретриверов библиотеки — сканирование исходников SDK векторной БД, а не кода приложения, поэтому фильтр для проверки существовать не может; честное, внутренне присущее ограничение, а не баг

Текущий прогон (2026-08-06) — версионированные свидетельства записаны в docs/benchmarks/v0.9.0.json:

РепозиторийСрабатыванияПравилаСтатус
openai-node, anthropic-sdk-typescript, anthropic-sdk-python, modelcontextprotocol/typescript-sdk, modelcontextprotocol/servers0—чисто
anthropics/skills (18 реальных skill-бандлов)0—чисто — чистая проверка точности для SKL001–005
vercel/ai (5 691 файл)0—было 40 (AI001, AI003, AI005, AI010, MCP002) до триажа — каждое вручную сверено с исходником и подтверждено как ложное срабатывание, прослежено до 3 независимых багов в корневой причине (см. ниже), исправлено и повторно подтверждено как чистое при полном повторном сканировании
run-llama/llama_index46VEC001внутренне присущее ограничение, а не баг — собственные обобщённые определения ретриверов библиотеки, где фильтр арендатора для поиска существовать не может
cisco-ai-defense/skill-scanner7SKL001, SKL002, SKL005все на фикстурах, помеченных как malicious/ — 6/6 в области действия, 0 на всём, что помечено как safe/

Триаж vercel/ai выявил три реальных бага в корневой причине — ни один не специфичен для правил навыков v0.6.0, все находятся в общей логике, используемой многими правилами:

  1. resolveLlmSink рассматривал любой вызов, разрешённый в модуль LLM SDK, как вызов модели, независимо от имени метода — помечая isToolUIPart (защитник типа, который пакет ai экспортирует прямо рядом с generateText) как вызов LLM. Только это вызвало 3 из 5 групп срабатываний (AI001, AI003, AI010).
  2. DANGEROUS_CALLEES в AI005 включает "query" для приёмников в стиле SQL-инъекций, но "query" также является допустимым глаголом вызова LLM/агента — claudeSdk.query({ prompt, options }), собственный вызов модели Claude Agent SDK, помечался как «вывод LLM, переданный в опасный приёмник» исключительно из-за общего имени метода.
  3. REQUEST_SOURCES (идентично продублированный в MCP002, MCP010, VEC003) сопоставлялся с голым "params." — любой параметр функции, традиционно названный params, не обязательно данные HTTP-запроса. Валидатор схемы URL (assertOpenLinkParams(params: unknown)) помечался как «URL MCP-сервера из пользовательского ввода».

Все три исправлены в корневой причине (а не в конкретном месте вызова) и закреплены как постоянные фикстуры в test-fixtures/. Полные подробности в CHANGELOG.md.

3. Проверка «уязвимая vs исправленная версия» — доказывает полноту, а не только точность.

Два описанных выше уровня проверяют только то, что сканер остаётся спокойным на безопасном коде. Проверки рекомендаций DEP003 валидируются в обратную сторону: закрепите пакет на документально уязвимой версии и подтвердите, что он помечается, затем закрепите его на исправленной версии и подтвердите, что он не помечается.```bash node --test test/dependency-guard.test.js

root@kitploit:~
covers: `[email protected]` (CVE-2025-6514, уязвим) помечен / `[email protected]` (исправлен) чист; `[email protected]` (до бэкдора) чист / `[email protected]` (после — для вредоносного пакета легитимного патча не существует) всё ещё помечен; `llama-cpp-python==0.2.71` (CVE-2024-34359, из набора, сгенерированного OSV) помечен / `==0.2.72` (исправлен) чист, в том числе с учётом нормализации имён в PyPI (`llama_cpp_python`); и спецификаторы без пиннинга вида `langchain>=0.1.0`, дающие **ноль** находок в отчёте по умолчанию. Сборка этого теста выявила реальный пробел: `DEP003` раньше сопоставлял уведомления только по имени пакета, никогда фактически не сравнивая заявленную версию с затронутым диапазоном из уведомления — исправлено в [`src/scanner/semver.ts`](https://github.com/akanthed/secureai-scan/blob/main/src/scanner/semver.ts).

Неоднозначность разрешается по-разному для каждого вида уведомлений — намеренно. **Вредоносный** пакет срабатывает, даже если заявленную версию не удаётся разрешить — установка бэкдора необратима, поэтому проверка завершается пометкой. **CVE** срабатывает на уровне `proven` только тогда, когда заявленная версия является точным пином, заведомо попадающим в затронутый диапазон; вариант без пиннинга, но возможно затронутый, понижается до `heuristic` (только с `--paranoid`). Применение правила для вредоносных пакетов к снимку CVE из 162 записей поставило бы критическую находку в каждом репозитории, где объявлен `langchain>=0.1.0` — непригодный к действию шум в масштабе.

## Roadmap

См. [`ROADMAP.md`](https://github.com/akanthed/secureai-scan/blob/main/ROADMAP.md) — что уже выпущено и что запланировано. Оба языковых движка основаны на AST: ts-morph для TypeScript/JavaScript и Tree-sitter для Python. Импорты, вызовы, присваивания, декораторы, области видимости, именованные аргументы, поля словарей и строки в Python являются узлами синтаксиса; целевой код никогда не импортируется и не выполняется, и интерпретатор Python не требуется. Оставшийся пробел Python ограничен глубиной межфункционального/межфайлового потока данных, а не парсингом. Производительность сканирования и известные ограничения задокументированы в [`docs/Performance.md`](https://github.com/akanthed/secureai-scan/blob/main/docs/Performance.md).

## Участие

Вклад приветствуется — см. [`CONTRIBUTING.md`](https://github.com/akanthed/secureai-scan/blob/main/CONTRIBUTING.md) о рабочем процессе и [`docs/WritingRules.md`](https://github.com/akanthed/secureai-scan/blob/main/docs/WritingRules.md) / [`docs/RuleDevelopment.md`](https://github.com/akanthed/secureai-scan/blob/main/docs/RuleDevelopment.md) о том, как добавить правило обнаружения, отвечающее указанной выше планке точности. Каждому новому правилу нужен фикстур как в [`test-fixtures/vulnerable/`](https://github.com/akanthed/secureai-scan/blob/main/test-fixtures/vulnerable), так и в [`test-fixtures/safe/`](https://github.com/akanthed/secureai-scan/blob/main/test-fixtures/safe), запись в `src/scanner/catalog.ts` и кейс в `test/corpus.test.js` — `npm test` обеспечивает соблюдение всех трёх.

## Лицензия

MIT © Akshay Kanthed
Скачать инструмент
LLM01 · MCP03
MCP010Команда/аргументы MCP stdio-сервера, сформированные из пользовательского ввода (RCE)LLM04 · MCP05
SKL001Невидимый/двунаправленный Unicode где-либо в пакете Agent SkillLLM01
SKL002Фразы инъекций, направляющих агента, в описании или теле навыка (обнаруживаются через обфускацию)LLM01
SKL003Содержимое навыка управляет тем, когда/как используется другой навык (затенение)LLM01
SKL004Многоэтапная/самораспаковывающаяся полезная нагрузка: непрозрачный блоб + инструкции по его декодированию и запускуLLM04 · MCP04
SKL005Чтение учётных данных + жёстко заданный внешний исходящий канал в сопутствующем файле пакетаLLM02 · MCP04
SKL006Выполнение команд во время загрузки через синтаксис динамической инъекции контекста Claude Code (!`cmd`/```!), до любого шлюза разрешений инструментовLLM04 · MCP05
SKL007Неограниченное разрешение Bash во frontmatter allowed-tools навыкаLLM03
SKL008Навык получает инструкции с внешнего URL и направляет агента следовать им («Circus of Skills»)LLM04
SKL009Навык сохраняет бэкдор, записывая в другой файл контекста (MEMORY.md/SOUL.md/AGENTS.md/CLAUDE.md)LLM05
SKL010Небезопасный тег десериализации YAML/JSON во frontmatter навыка или в прилагаемом конфигурационном файлеLLM04
VEC001Векторный поиск без фильтра арендатора/пользователяLLM09
VEC002Неограниченный или управляемый пользователем лимит поискаLLM06
VEC003Пользовательский контент, загружаемый в общее векторное хранилищеLLM05
VEC004Загрузка без тегирования арендатора/пространства имёнLLM09
DEP001Имя зависимости не найдено в реестре (опционально --check-dependencies)LLM04
DEP002Имя зависимости на одно изменение от популярного пакета (опционально)LLM04
DEP003Зависимость с задокументированным вредоносным релизом или критической CVE — проверяется офлайн при каждом сканировании, с учётом диапазона версий (postmark-mcp, mcp-remote CVE-2025-6514, …)LLM04 · MCP04
LLC001Жёстко заданный секрет в config.yaml прокси LiteLLMLLM02
LLC002api_base прокси LiteLLM доступен по незашифрованному HTTPLLM04
LLC003В конфигурации прокси LiteLLM нет секции guardrails: (эвристика, только --paranoid)LLM03