Скил - это удобно ровно до того момента, пока он не получает доступ к данным и командам. А он получает: ходит в сеть, читает файлы, дёргает API, иногда исполняет команды. И вот тут один невнимательный скил превращается в открытую дверь. Ты хотел автоматизировать рутину, а заодно положил ключ под коврик и оставил его всем желающим.
Беда в том, что дыры в скилах выглядят безобидно. Ключ, вписанный прямо в текст скила, - “ну я же только для себя”. Запрет “опасных” команд по списку - “вроде всё перекрыл”. Права пошире - “на всякий случай, чтоб не переделывать”. Каждое решение по отдельности кажется разумным. А вместе это решето, через которое утекают секреты и проходят чужие команды.
И есть вторая беда, тише первой: скил-графоман. Он делает слишком много. Удаляет, публикует, шлёт наружу - там, где его об этом не просили. Чем больше скил умеет, тем больше у него способов навредить. Поэтому разговор про безопасность скилов - это не только “как закрыть дыры”, но и “что скилу вообще не положено трогать”.
В чём идея
Безопасность скила сводится к нескольким простым правилам, и их легко проверять - хоть по чек-листу, хоть руками одного скила-аудитора, который читает другой скил и говорит, где рискованно.
Правило первое - инъекции. Если скил берёт текст из запроса пользователя или из ответа внешнего сервиса и подставляет его прямо в команду или в адрес - это дыра. Чужой текст не должен попадать в команду как есть: его место - аргумент, а не часть самой команды. Иначе тот, кто пишет запрос, по сути пишет тебе команды.
Правило второе, и оно ломает интуицию, - allowlist вместо denylist. Denylist это “запрещаю вот эти плохие штуки”. Звучит надёжно, а на деле это решето: ты перечисляешь то, что вспомнил, а злоумышленник находит то, что ты забыл. Allowlist наоборот: “разрешено только вот это, короткий список, остальное - нет”. Белый список почти всегда короче чёрного и не оставляет щелей.
Правило третье - секрет-гигиена. Ключи и пароли живут в окружении (env) или в менеджере секретов, а не в тексте скила, не в команде и не в логах. Секрет, переданный через аргумент команды, виден в истории и логах - это тот же самый секрет в коде, только сбоку. Правило простое: в файле скила не должно быть ни одного ключа.
Правило четвёртое - минимум прав. Скил просит ровно столько доступа, сколько нужно для задачи. Не “доступ ко всем папкам и сети на всякий случай”, а строго необходимое. Чем уже права, тем меньше радиус поражения, если что-то пойдёт не так.
И главное, ради чего весь урок: лучшая фича скила - то, что он сознательно НЕ делает. У хорошего скила есть явная граница: он не удаляет, не публикует, не отправляет данные наружу, если это не его задача. Эта граница - не недоработка, а защита. Чем уже то, что скил умеет, тем меньше у него способов навредить. А иногда самый безопасный скил - тот, которого нет: если задачу спокойно решает обычная просьба к ассистенту, отдельный скил с доступами не нужен.
Почему это работает? Потому что безопасность - это не про длинный список запретов, а про сужение возможностей. Меньше прав, меньше секретов в коде, короче белый список, уже граница - меньше поверхности для атаки. А проверять всё это можно механически, по пунктам, что и делает скил-аудитор.
Как себе сделать
Не проверяй скилы руками по памяти - отдай это своему ассистенту. Claude Code, GitHub Copilot, Cursor, Gemini - любой. Пусть он сам пройдёт по чек-листу и выдаст вердикт. Просто скопируй промпт:
Создай мне скил-аудитор, который проверяет другой скил на безопасность.
Срабатывай на просьбы вроде "проверь скил на безопасность", "сделай аудит скила", "что не так с этим скилом".
Аудитор читает проверяемый скил (его описание и вспомогательные файлы) и проходит по чек-листу, для каждого пункта помечает ok или risk с короткой причиной:
1) инъекции - чужой текст из запроса или из внешнего ответа не должен попадать в команду или адрес как есть;
2) allowlist вместо denylist - перечислено, что разрешено, а не попытка запретить всё плохое;
3) секрет-гигиена - ключи берутся из окружения, а не лежат в тексте скила, в команде или в логах;
4) минимум прав - запрошено ровно столько доступа, сколько нужно, без широких прав на всякий случай;
5) чистое окружение - скил не тащит за собой лишние переменные окружения и не светит их в выводе или логах;
6) что скил сознательно НЕ делает - есть ли у него явная граница (не удаляет, не публикует, не шлёт наружу).
В конце дай вердикт: pass, warn или fail. Ставь fail, если есть секрет в коде, инъекция или denylist вместо allowlist.
Аудитор только читает и пишет отчёт - он не исполняет проверяемый скил и не меняет файлы.
Как понять, что заработало: подсунь аудитору заведомо дырявый скил - с ключом прямо в тексте и с запретом по списку. Если он сам, без подсказок, пометит секрет и denylist как risk и выдаст вердикт fail с парой правок - аудитор живой. Дальше прогоняй через него любые свои скилы перед тем, как давать им доступы.
И главное держи в голове, когда пишешь скил: сначала спроси, нужен ли он вообще, а потом - что он сознательно делать НЕ будет. Самая надёжная защита - это возможность, которой у скила просто нет.
Смотреть полностью
- YouTube: https://www.youtube.com/watch?v=16VfQpzEgV0
- VK Видео: https://vk.com/video-233222565_456239062
- Rutube: https://rutube.ru/video/668c6ed77d984d2e3cadd5ecdd30c21f/
Коротко
- YouTube Shorts: https://www.youtube.com/shorts/TIvhIuZiy9I
- VK Клипы: https://vk.com/clip-233222565_456239063
- Rutube: https://rutube.ru/video/c3d5d20eb02e7470eabad9838690c8ff/
- Telegram: https://t.me/chernovdev/2136
