Безопасность OpenSkills
Что вы узнаете
- Понимание трехуровневой системы защиты OpenSkills
- Знание принципов и методов защиты от обхода путей
- Освоение безопасной обработки символических ссылок
- Осознание рисков ReDoS и защитных мер при парсинге YAML
Ваша текущая проблема
Возможно, вы слышали утверждение "локальное выполнение безопаснее", но не знаете конкретных мер безопасности. Или вы беспокоитесь при установке скиллов:
- Будут ли файлы записаны в системные каталоги?
- Могут ли символические ссылки представлять угрозу безопасности?
- Возможны ли уязвимости при парсинге YAML в SKILL.md?
Когда использовать
Когда вам нужно:
- Развернуть OpenSkills в корпоративной среде
- Провести аудит безопасности OpenSkills
- Оценить решение по управлению скиллами с точки зрения безопасности
- Пройти технический аудит со стороны команды безопасности
Основная идея
Дизайн безопасности OpenSkills следует трем принципам:
Трехуровневая система защиты
- Валидация входных данных - Проверка всех внешних входов (пути, URL, YAML)
- Изолированное выполнение - Обеспечение операций в ожидаемых каталогах
- Безопасный парсинг - Защита от уязвимостей парсера (ReDoS)
Локальное выполнение + отсутствие загрузки данных + валидация входов + изоляция путей = безопасное управление скиллами
Защита от обхода путей
Что такое атака обхода путей
Обход путей (Path Traversal) - это атака, при которой злоумышленник использует последовательности типа ../ для доступа к файлам за пределами ожидаемого каталога.
Пример: Без защиты злоумышленник может попытаться:
# Попытка установки в системный каталог
openskills install malicious/skill --target ../../../etc/
# Попытка перезаписи файла конфигурации
openskills install malicious/skill --target ../../../../.ssh/Механизм защиты OpenSkills
OpenSkills использует функцию isPathInside для проверки, что путь установки находится внутри целевого каталога.
Расположение в исходном коде: src/commands/install.ts:71-78
function isPathInside(targetPath: string, targetDir: string): boolean {
const resolvedTargetPath = resolve(targetPath);
const resolvedTargetDir = resolve(targetDir);
const resolvedTargetDirWithSep = resolvedTargetDir.endsWith(sep)
? resolvedTargetDir
: resolvedTargetDir + sep;
return resolvedTargetPath.startsWith(resolvedTargetDirWithSep);
}Принцип работы:
- Использование
resolve()для преобразования всех относительных путей в абсолютные - Нормализация целевого каталога, обеспечение завершения разделителем путей
- Проверка, начинается ли целевой путь с целевого каталога
Проверка при установке (src/commands/install.ts:257-260):
if (!isPathInside(targetPath, targetDir)) {
console.error(chalk.red('Security error: Installation path outside target directory'));
process.exit(1);
}Проверка эффективности защиты
Сценарий теста: Попытка атаки обхода путей
# Нормальная установка (успешно)
openskills install anthropics/skills
# Попытка использования ../ (неудачно)
openskills install malicious/skill --target ../../../etc/
# Security error: Installation path outside target directoryЧто вы должны увидеть: Любая попытка установки за пределами целевого каталога будет отклонена с отображением ошибки безопасности.
Безопасность символических ссылок
Риски символических ссылок
Символическая ссылка (Symlink) - это ярлык, указывающий на другой файл или каталог. При неправильной обработке это может привести к:
- Утечке информации - Злоумышленник создает символическую ссылку на конфиденциальный файл
- Перезаписи файлов - Символическая ссылка указывает на системный файл, который перезаписывается операцией установки
- Циклическим ссылкам - Символическая ссылка указывает на себя, вызывая бесконечную рекурсию
Разыменование при установке
OpenSkills использует dereference: true при копировании файлов для разыменования символических ссылок, напрямую копируя целевой файл.
Расположение в исходном коде: src/commands/install.ts:262
cpSync(skillDir, targetPath, { recursive: true, dereference: true });Эффект:
- Символические ссылки заменяются фактическими файлами
- Сама символическая ссылка не копируется
- Избегает перезаписи файлов, на которые указывают символические ссылки
Проверка символических ссылок при поиске скиллов
OpenSkills поддерживает скиллы в виде символических ссылок, но проверяет их на повреждение.
Расположение в исходном коде: src/utils/skills.ts:10-25
function isDirectoryOrSymlinkToDirectory(entry: Dirent, parentDir: string): boolean {
if (entry.isDirectory()) {
return true;
}
if (entry.isSymbolicLink()) {
try {
const fullPath = join(parentDir, entry.name);
const stats = statSync(fullPath); // statSync follows symlinks
return stats.isDirectory();
} catch {
// Broken symlink or permission error
return false;
}
}
return false;
}Характеристики безопасности:
- Использование
statSync()для следования за символическими ссылками и проверки цели - Поврежденные символические ссылки пропускаются (блок
catch) - Не вызывает сбоя, тихая обработка
Сценарии использования
Поддержка символических ссылок позволяет вам:
- Использовать скиллы напрямую из git-репозитория (без копирования)
- Синхронизировать изменения при локальной разработке
- Делиться библиотекой скиллов между проектами
Безопасность парсинга YAML
Риск ReDoS
Отказ регулярных выражений (ReDoS) - это когда злонамеренно созданный ввод вызывает экспоненциальное время сопоставления регулярных выражений, потребляя ресурсы CPU.
OpenSkills должен парсить YAML frontmatter в SKILL.md:
---
name: skill-name
description: Skill description
---Защита с использованием нежадных регулярных выражений
OpenSkills использует нежадные регулярные выражения для предотвращения ReDoS.
Расположение в исходном коде: src/utils/yaml.ts:4
export function extractYamlField(content: string, field: string): string {
const match = content.match(new RegExp(`^${field}:\\s*(.+?)$`, 'm'));
return match ? match[1].trim() : '';
}Ключевые моменты:
+?- это нежадный квантификатор, соответствующий кратчайшему возможному^и$фиксируют начало и конец строки- Соответствует только одной строке, избегая сложной вложенности
Неправильный пример (жадное сопоставление):
// ❌ Опасно: + будет жадно сопоставлять, может встретить взрыв обратного отслеживания
new RegExp(`^${field}:\\s*(.+)$`, 'm')Правильный пример (нежадное сопоставление):
// ✅ Безопасно: +? нежадно, останавливается при первом символе новой строки
new RegExp(`^${field}:\\s*(.+?)$`, 'm')Разрешения файлов и проверка источника
Наследование системных разрешений
OpenSkills не управляет разрешениями файлов, напрямую наследуя управление разрешениями операционной системы:
- Владелец файлов совпадает с пользователем, запускающим OpenSkills
- Разрешения каталогов следуют настройкам umask системы
- Управление разрешениями унифицировано контролируется файловой системой
Проверка источника для частных репозиториев
При установке из частного git-репозитория OpenSkills полагается на проверку SSH-ключей git.
Расположение в исходном коде: src/commands/install.ts:167
Рекомендация
Убедитесь, что ваш SSH-ключ настроен правильно и добавлен в список авторизованных ключей git-сервера.
Безопасность локального выполнения
OpenSkills - это чисто локальный инструмент, не включающий сетевое взаимодействие (кроме клонирования git-репозиториев):
Отсутствие загрузки данных
| Операция | Поток данных |
|---|---|
| Установка скилла | Git-репозиторий → Локальный |
| Чтение скилла | Локальный → Стандартный вывод |
| Синхронизация AGENTS.md | Локальный → Локальный файл |
| Обновление скилла | Git-репозиторий → Локальный |
Защита конфиденциальности
- Все файлы скиллов хранятся локально
- AI-агенты читают через локальную файловую систему
- Отсутствие облачных зависимостей или сбора телеметрии
Различие с Marketplace
OpenSkills не зависит от Anthropic Marketplace, работает полностью локально.
Резюме урока
Трехуровневая система защиты OpenSkills:
| Уровень безопасности | Меры защиты | Расположение исходного кода |
|---|---|---|
| Защита от обхода путей | isPathInside() проверяет, что путь находится внутри целевого каталога | install.ts:71-78 |
| Безопасность символических ссылок | dereference: true разыменовывает символические ссылки | install.ts:262 |
| Безопасность парсинга YAML | Нежадное регулярное выражение +? предотвращает ReDoS | yaml.ts:4 |
Запомните:
- Атаки обхода путей используют последовательности
../для доступа к файлам за пределами ожидаемого каталога - Символические ссылки требуют разыменования или проверки во избежание утечки информации и перезаписи файлов
- Парсинг YAML использует нежадные регулярные выражения для предотвращения ReDoS
- Локальное выполнение + отсутствие загрузки данных = более высокая конфиденциальность и безопасность
Предпросмотр следующего урока
В следующем уроке мы изучим Лучшие практики.
Вы узнаете:
- Лучшие практики настройки проекта
- Решения по командной работе для управления скиллами
- Советы по использованию в мульти-агентной среде
- Распространенные ловушки и способы их избежания
Приложение: Справочник по исходному коду
Нажмите, чтобы раскрыть расположение исходного кода
Время обновления: 2026-01-24
| Функция | Путь к файлу | Номер строки |
|---|---|---|
| Защита от обхода путей | src/commands/install.ts | 71-78 |
| Проверка пути установки | src/commands/install.ts | 257-260 |
| Разыменование символических ссылок | src/commands/install.ts | 262 |
| Проверка пути обновления | src/commands/update.ts | 156-172 |
| Проверка символических ссылок | src/utils/skills.ts | 10-25 |
| Безопасность парсинга YAML | src/utils/yaml.ts | 4 |
Ключевые функции:
isPathInside(targetPath, targetDir): Проверка, что целевой путь находится внутри целевого каталога (предотвращает обход путей)isDirectoryOrSymlinkToDirectory(entry, parentDir): Проверяет, является ли каталог или символическая ссылка указателем на каталогextractYamlField(content, field): Извлекает поля YAML с использованием нежадных регулярных выражений (предотвращает ReDoS)
Журнал изменений:
CHANGELOG.md:64-68- Описание обновления безопасности v1.5.0