
Сканер только для чтения настроек git, которые позволяют репозиторию выполнять код в агентах программирования (Claude Code, Codex, Cursor, Copilot). Охватывает класс GitSpawn и CVE-2026-45033. Без зависимостей, без сети, без телеметрии.
Репозиторий, который заставит вашего агента кодинга выполнить код, как только он откроет папку. GuardSkill проверяет это до того, как вы это сделаете.
npx guardskill .
Только чтение. Никаких сетевых запросов, никакой телеметрии, никакой конфигурации, никакой учётной записи. Он читает конфигурацию git и скрипты хуков, выводит найденное и завершает работу.
Агенты кодинга собирают контекст, выполняя обычные команды git — git status, git diff — как только открывают проект. Git читает свои настройки из собственного .git/config репозитория, и несколько из этих настроек указывают программу, которую git должен выполнить. Поместите команду в core.fsmonitor — и она выполнится с вашими привилегиями, вне любой песочницы, до того, как вы что-либо введёте.
Два фрагмента публичных исследований делают это конкретным:
.git/config.git каталогом@github/copilot 1.0.43 путём принудительного safe.bareRepository=explicit. (GitHub Advisory)Рекомендуемое пользовательское смягчение в обоих отчётах одинаково: проверьте конфигурацию git перед тем, как открыть каталог с агентом. Вручную делать это по всему дереву утомительно. Этот инструмент делает это за секунду.
GuardSkill обходит дерево и находит каждую конфигурацию git, которую агент мог бы подхватить: собственный .git проекта, любой вложенный .git, прибывший как содержимое, любой голый репозиторий, скрытый в подкаталоге, файл .git, оставленный подмодулем или связанным рабочим деревом, а также конфиги, которые git хранит рядом с основным — config.worktree и каждый .git/modules/<name>/config. Каждый из них проверяется.
| Класс | Проверки |
|---|---|
| Ключи прямого выполнения | core.fsmonitor, core.sshCommand, core.gitProxy, core.pager, core.editor, sequence.editor, diff.external, uploadpack.packObjectsHook |
| Ключи косвенного выполнения | filter.*.clean / .smudge / .process, diff.*.textconv, merge.*.driver, mergetool.*.cmd, difftool.*.cmd, credential.helper |
| Псевдонимы оболочки | любой alias.*, значение которого начинается с ! |
| Конфигурация, загружаемая из другого места | include.path, includeIf.*.path |
| Хуки | переопределения core.hooksPath, активные (не .sample) скрипты в .git/hooks, а также скрипты хуков, которые передают загрузку в оболочку или декодируют base64 перед выполнением |
| Транспорты | protocol.allow и protocol.<name>.allow, возвращённые к always, и любой URL удалённого репозитория или подмодуля, использующий транспорт ext::, который передаёт остаток строки оболочке |
| Структура | голые репозитории внутри дерева (вектор CVE-2026-45033), вложенные каталоги .git, не являющиеся зарегистрированными подмодулями, файлы .git, указывающие на git-каталог внутри дерева |
npx guardskill . # сканировать текущий проект
npx guardskill ~/code/some-project # сканировать конкретный путь
npx guardskill . --json # машиночитаемый вывод
npx guardskill . --out report.md # также записать отчёт в Markdown
npx guardskill . --fail-on critical # завершать сборку только при критических находках
npx guardskill . --exclude test/fixtures # пропустить каталог
Коды выхода: 0 — ничего на пороге или выше, 1 — находки на пороге или выше (порог по умолчанию: high), 2 — само сканирование завершилось ошибкой.
В CI:
- name: Check for git execution vectors
run: npx guardskill . --fail-on high
Пример вывода:
GuardSkill - git execution-vector scan (read-only)
Path: /Users/dev/projects/inherited-project
Git configurations inspected: 2 Directories walked: 148
[CRITICAL] vendor/payload.git - Bare git repository found inside the project tree
what Git discovers bare repositories while walking directories and applies their
configuration, including keys that execute commands.
found bare repository at vendor/payload.git
do Do not open this project with a coding agent until you have inspected the directory.
[CRITICAL] vendor/payload.git/config:3 - core.fsmonitor runs an external command
found core.fsmonitor = /tmp/.x/run.sh
2 critical, 0 high, 0 medium, 0 low.
Nothing was changed - this scan only reads.
Инструмент безопасности, который кричит «волк», удаляют. Набор тестов запускается на 29 реалистичных чистых репозиториях — git-lfs, git-crypt, husky, соглашение .githooks, зарегистрированные подмодули, помощники учётных данных, пользовательские редакторы и пейджеры, конфигурация подписи — и сборка завершается ошибкой, если любой из них даёт находку выше информационного уровня. Он запускается на 22 репозиториях, построенных вокруг известного паттерна атаки, и завершается ошибкой, если какая-либо из них пропущена или поймана не тем правилом.
Поверх этого находится набор для обхода: каждый случай в нём был найден путём атаки на версию GuardSkill, которая уже прошла собственные тесты, и он запускается на каждом коммите, чтобы будущее изменение не могло тихо открыть его снова. Он покрывает тот же ключ, записанный всеми способами, которые git всё ещё принимает (регистр, кавычки, продолжения строк, CRLF, метка порядка байтов, ключ в строке раздела), полезные нагрузки, названные в честь знакомых инструментов, каталоги хуков, названные .husky для видимости рутинности, и конфиги, скрытые там, куда первая версия никогда не заглядывала. Набор на устойчивость подаёт ему бинарные, пустые, усечённые и конфиги на 200 000 строк, недоступные для чтения каталоги, циклы символьных ссылок и указатели, направленные за пределы дерева, и требует отчёт, а не трассировку стека.
Два осознанных проектных решения:
.githooks сообщаются как информационные (low), а не как риск — но GuardSkill всё равно читает скрипты и повышает до critical, если один из них загружает или декодирует код перед выполнением.include / includeIf сообщается всегда. Include может позже внести любой ключ из этого списка — именно так вы бы и спрятали его. Общий ~/.gitconfig, написанный вами самими, — это обычная находка, которую можно отклонить..husky, запускающий npm test, — информационный, и находка перечисляет, что будет выполняться. Тот же каталог, запускающий что-то из /tmp, — нет.Он ничего не изменяет, никогда. Он не выполняет ничего из найденного. Он не делает сетевых запросов и не собирает телеметрию — запустите его офлайн, и он поведёт себя идентично. Он пока не сканирует npm-зависимости, .claude/settings.json, .vscode/tasks.json или определения MCP-серверов; это следующий класс, не этот. И это сигнал, а не вердикт: прочитайте находку, посмотрите на доказательства, решите сами.
SKILL.md в этом репозитории позволяет агенту кодинга запустить сканирование самостоятельно перед открытием незнакомого проекта. Скопируйте каталог в папку навыков или укажите вашему агенту на репозиторий.
npm test # перегенерирует фикстуры, затем запускает набор тестов
Фикстуры генерируются кодом (test/fixtures/generate.js), а не фиксируются вручную, поэтому расширение чистого или уязвимого набора — это несколько строк. Новые правила обнаружения помещаются в rules/git-exec-keys.json — правило без фикстуры с обеих сторон не будет объединено.
Непрерывный мониторинг, оповещения Slack/Teams и автоматические pull-запросы с исправлениями планируются как платный уровень. Сам сканер остаётся бесплатным и под лицензией MIT. Правила обнаружения остаются в открытом репозитории — инструменту безопасности, чьи правила вы не можете прочитать, доверять не стоит.
MIT. Создано и поддерживается Helios IT Solutions, голландским поставщиком ИТ-услуг. Вопросы безопасности: см. SECURITY.md.