Как не нарваться на prompt-injection или зачем нам проверять скиллы?

от автора

В прошлой статье говорили про использования LLM хакерами, и обещал как раз продолжение, как защищить свое рабочее пространство, ну в общем, к делу 🙂

Когда последний раз вы проверяли библиотеку на уязвимости? Или софт, что вы ставите и используете — проверяли? Ну, вот и я также — почти что никогда (раньше)

Суть вот в чем, мы в одной из прошлых статей то и обсуждали, что разработка своих скиллов — это естественная история, но и использование oss скилов — аналогично, особенно когда эти скиллы не просто MD файл, а полноценный инструмент взаимодействия

Но, проблема в том, что скилл это не конфиг и не просто “промпт” в SKILL.md — это буквально может быть и исполняемым кодом и самое важное — с твоими правами 🙂

Меня зовут Эдгар Сипки. Я инженер и более 10 лет работаю с backend-системами, AI / LLM-инструментами. Выступаю на AI Conf, TeamLead Conf, HighLoad, отбираю доклады на Golang Conf в программном комитете.
А в своём тг-канале делюсь прикладными AI-инструментами и подходами для разработки — подписывайтесь 🙂

Но, зачем мне боятся то скиллов?

Есть исследование на 42 447 скиллов с маркетплейсов, и в итоге 26.1% содержат уязвимости, 5.2% — скорее всего вредоносные. Но и это еще не все, каждый четвёртый — с дырой, f каждый двадцатый — закладка, к примеру промпт-инъекции, сбор env-переменных с твоими ключами, отправка контекста наружу, в общем полный набор

А, кстати, еще 🙂

Скиллы с исполняемыми скриптами уязвимы в 2.12 раза чаще, лежит в скилле .py или .sh — проверять обязательно стоит

Но, как говорится

Как защититься?

NVIDIA выкатили SkillSpector — сканер скиллов ДО установки, а ставится одной строкой:

uv tool install git+https://github.com/NVIDIA/skillspector.git# альтернативы: сборка из исходников (git clone + make install) или Docker - см. README проекта# (в PyPI пакета skillspector нет, pip/pipx install skillspector не сработает)

И дальше просто:

skillspector scan <https://github.com/owner/repo> --format terminal

Что умеет:

  • на вход — git-URL, zip, директория или одиночный SKILL.md;

  • 64+ паттерна в 16+ категориях (в новых релизах уже 68/17): инъекции, эксфильтрация, тайпсквоттинг, MCP tool poisoning и пр.;

  • два этапа: быстрая статика (regex/AST/YARA/OSV.dev), а поверх — опциональный LLM-анализ для оценки намерения;

  • на выходе — risk_score 0-100, вердикт SAFE / CAUTION / DO_NOT_INSTALL и отчёт в terminal / json / markdown / sarif.

А сам-то сканер не словит инъекцию?

И вот тут у меня прокрались сомнения как раз таки, ведь в чем суть, сам сканер работает не просто проверяя по ключевым словам (но да, это конечно тоже) но и проверяет же также через llm, то первое о чем я задумался: если внутри скилла лежит злая инструкция, а SkillSpector скармливает его LLM — не уговорит ли скилл сканер сказать «всё чисто»? Короткий ответ — “нет”, и вот почему

  1. Статика идёт первой и она детерминированная. Regex/AST/YARA/проверка зависимостей не «читают» инструкции — они матчат паттерны. Уговорить regex невозможно.

  2. LLM здесь — классификатор, а не агент. У него нет инструментов, файловой системы и сети. Его единственный выход — структурный вердикт (JSON), он физически ничего не может «сделать» по просьбе скилла.

  3. В промпте анти-джейлбрейк. Стадия намеренно защищена от «проигнорируй прошлые инструкции».

  4. Сама попытка инъекции — это улика. Текст вида «ignore previous instructions» триггерит паттерны Instruction Override / Hidden Instructions. То есть инъекция не прячется от сканера, а наоборот подсвечивает скилл.

SkillSpector обрабатывает содержимое скилла как данные для анализа, а не как команды к исполнению. Ровно этого не хватает уязвимым агентам — они принимают чужой текст за свои инструкции 🙂

P.S. Да, поэтому явно точно не стоит проверять скиллы своим же кодинг агентом

Короче говоря: сканер сдвигает шансы в твою пользу, но думать всё равно тебе 🙂

Автоматизация, автоматизация и снова автоматизация 🙂

Главная боль из исследования — не «нет инструмента», а «я забываю им пользоваться». Поэтому делаем так, чтобы проверка происходила сама, я рекомендую создать алиас который резолвит репо, прогоняет SkillSpector и ставит скилл, только если он прошёл:

# ~/.zshrc | ~/.bashrc# deps: Node (npx) + uv (uv tool install git+https://github.com/NVIDIA/skillspector.git)safeskill() {  local repo="$1"  [ -z "$repo" ] && { echo "usage: safeskill <owner/repo>"; return 2; }  echo "🔍 SkillSpector проверяет $repo ..."  skillspector scan "<https://github.com/$repo>" --format terminal  local scan_exit=$?  case "$scan_exit" in    0)      echo "✅ risk_score <= 50 - ставлю скилл"      npx skills add "$repo"      ;;    1)      echo "⚠️  risk_score > 50 (DO_NOT_INSTALL) - смотри находки выше."      printf "Всё равно установить %s? [y/N] " "$repo"      read -r REPLY      case "$REPLY" in        [yY]|[yY][eE][sS])          echo "⚠️  ставлю несмотря на предупреждение скана"          npx skills add "$repo"          ;;        *)          echo "Отменено."          return 1          ;;      esac      ;;    *)      echo "⛔ скан упал (exit=$scan_exit)"      return 2      ;;  esac}

Теперь вместо npx skills add owner/repo ты пишешь safeskill owner/repo — и в итоге тебе явно тяжелее продолбаться с этой историей

А если скан ругается, но ты всё равно хочешь поставить — алиас спросит подтверждение [y/N], так что финальное решение остаётся за тобой.

Алиас — это для рук. Но в эпоху antigravity, cursor agent mode, vs code agent и так далее, где ты уже даже прямого доступа к терминалу не имеешь — я сделал скилл, который заставит агента сам проверять новый скилл перед установкой 🙂

Что в итоге

Короче, скиллы — это суперсила, и отказываться от них глупо. А самая важная мысль, ребята, «разделяте данные и инструкции» ведь ровно это нехватает нам.

И самое важное, не забываете что скиллы и агенты часто работают имея полностью вшаи же права, так что не забывайте проверять.

Пусть агент остаётся 🐢, который думает, а не ⚡, который слепо исполняет 🙂

ссылка на оригинал статьи https://habr.com/ru/articles/1054508/