【免费下载链接】opendirectory
AI Agent Skills built for Founders who hate Marketing
OpenDirectory 是一个面向 AI Agent 的开放 Skill 市场(skill marketplace),内置 64 个可一键安装的营销与增长技能。由于 Skill 里可能包含脚本、会被 AI Agent 直接执行,"开放贡献"天然带有供应链风险。本文将完整拆解 OpenDirectory 的两道核心防线——路径边界防护(path-boundary guard)与恶意代码扫描(malicious code scan),看看一个开放的 Skill 市场如何把风险拦在安装之前与运行之时。
为什么开放 Skill 市场需要安全设计?
对新手来说,使用体验很简单:一条命令浏览、搜索并安装技能,无需全局安装。
npx "@opendirectory.dev/skills" install <skill-name> --target claudeCLI 会把 Skill 复制到对应 Agent 的技能目录,例如~/.claude/skills/、~/.codex/skills/,各 Agent 的安装位置统一维护在 packages/cli/src/detect.ts 的AGENT_PATHS映射表中。
但"开放"意味着任何人可以提交 Skill,而 Skill 中的.py/.js/.sh脚本可能被 Agent 执行。OpenDirectory 的解法不是靠"人肉盯防",而是把安全规则写进 CI 和 CLI 代码里,形成三道防线:
| 防线 | 触发时机 | 核心手段 |
|---|---|---|
| 第一道 | PR 提交时 | 恶意代码扫描 + 危险文件类型拦截 |
| 第二道 | 安装/卸载/更新时 | 路径边界防护,拒绝越界写入与删除 |
| 第三道 | 更新与落盘时 | 备份回滚 + 原子写,失败可恢复 |
第一道防线:安装前的恶意代码扫描
每个 PR 都会触发.github/workflows/pr-validation.yml自动化流水线,其中关键的校验步骤包括:
- Validate skills structure:运行 scripts/validate-pr.ts 对每个 Skill 目录做安全扫描
- Validate skill descriptions:校验技能描述规范
- Enforce registry sync:强制 packages/cli/registry.json 与
skills/目录保持同步,防止"幽灵技能"混入 - Build CLI + E2E tests:构建并跑端到端测试,确保防护逻辑真实生效
1. 危险文件类型直接拒收
扫描器会递归遍历 Skill 目录(跳过node_modules与.git),一旦发现可执行或压缩类文件立即报错:
Disallowed file extension found: skills/xxx/malware.exe被禁的扩展名包括.exe、.dll、.bat、.zip、.gz、.tar——一个 Skill 里出现这些文件,PR 直接失败。
2. 危险命令模式匹配
对.sh、.py、.js、.ts文件,扫描器会用一组正则"黑名单"做内容匹配(见 scripts/validate-pr.ts#L10-L16):
| 危险模式 | 典型风险 |
|---|---|
rm -rf / | 清空磁盘 |
curl ... \| bash | 下载并远程执行未知脚本 |
wget ... \| sh | 同上,管道执行 |
eval(/exec( | 动态执行任意代码 |
命中任意一条,CI 会输出Dangerous pattern ... found in file并让流水线以非零码退出,PR 无法合并。
3. 自动化扫描 + AI Review + 人工合并
根据 CONTRIBUTING.md 的贡献流程,PR 合并前还需经过三层审核:
- Security Scan:GitHub Actions 严格扫描代码格式与恶意软件(malware)
- AI Review:由 Greptile 与 GitHub Copilot 对 PR 做智能审查
- Human Merge:全部通过后,由人工维护者执行最终合并并发布到 NPM
也就是说,恶意代码扫描不是"扫一次就完事",而是自动化规则 + AI 审查 + 人工兜底的组合拳。
第二道防线:运行时的路径边界防护
第一道防线挡住了"提交进来的恶意",第二道防线则解决另一个问题:即使名字合法,安装过程能否被诱导写出/删掉不该碰的文件?这正是路径遍历(path traversal)攻击的典型场景——比如用../../etc这类名字试图跳出目录。
OpenDirectory 的 CLI 对安装、卸载、更新三个操作都设置了同一种"路径边界守卫":解析出真实路径后,计算它相对于合法根目录的相对路径,只要相对路径以..开头、是绝对路径或为空,就立即拒绝。
安装时的边界检查
安装入口在 packages/cli/src/install-core.ts,核心逻辑非常直白:
// Path-boundary guard: verify resolved skillDir stays inside skills/ const skillsRoot = path.resolve(root, 'skills'); const resolvedSkillDir = path.resolve(skillDir); const rel = path.relative(skillsRoot, resolvedSkillDir); if (rel.startsWith('..') || path.isAbsolute(rel) || rel.length === 0) { // Refusing to install: resolved path is outside the skills directory. }三个判断条件分别堵住:跳出skills/目录(..前缀)、指向系统其他位置(绝对路径)、退化到根目录本身(空字符串)。越界时 CLI 会明确报错:
Refusing to install '...': resolved path is outside the skills directory.卸载与更新同样受保护
恶意内容如果藏在"已安装清单"(manifest)里,也可能借卸载/更新环节搞破坏。OpenDirectory 对这两个操作做了同样的边界校验:
- 卸载:packages/cli/src/uninstall-core.ts 校验清单中的路径必须位于对应 Agent 的 skills 目录内,否则报
Refusing to remove ...: path is outside the agent's skills directory.——即使清单被篡改指向~/.ssh之类的位置,也不会被删除 - 更新:packages/cli/src/update-core.ts 用同样的"相对路径前缀 + 绝对路径"双重判断,越界即拒绝
| 操作 | 边界根目录 | 越界时的行为 |
|---|---|---|
| install | CLI 包内的skills/ | 拒绝复制,报Refusing to install |
| uninstall | Agent 的skills/目录(如~/.claude/skills/) | 拒绝删除,报Refusing to remove |
| update | Agent 的skills/目录 | 拒绝更新,报Refusing to update |
Skill 的发现过程本身也有约束:packages/cli/src/skill-discovery.ts 把SKILL.md的搜索深度限制在 4 层以内,并忽略.git、node_modules目录,避免在无关目录中误认技能。
第三道防线:更新回滚与安全落盘
防线不止于"拒绝",还要保证"失败时不留下烂摊子"。
更新失败自动回滚
执行update <skill-name>时,packages/cli/src/update-core.ts 的流程是:
- 先把旧版本
rename成.bak.<pid>.<时间戳>备份 - 再安装新版本
- 若安装失败,自动删掉新装内容并把备份还原
- 只有在"更新失败且回滚也失败"的极端情况下,才提示手动恢复,并给出备份的精确路径
配合 packages/cli/README.md 中update命令的说明(safe rollback if the new install fails),这是一条完整的失败恢复链路。
清单与写入操作的"原子化"安全
- 清单读取带结构校验:packages/cli/src/manifest.ts 读取
~/.opendirectory/installed.json时会校验skills必须是数组,损坏或畸形的清单文件会被安全地当作空清单处理,而不是崩溃 - 清单写入采用"临时文件 + rename":见 packages/cli/src/manifest.ts#L40-L46,先写
.tmp.<pid>再原子替换,进程中断也不会留下半截的 JSON - 文件写入统一走安全封装:packages/cli/src/fs-adapters.ts 的
resolvePath/safeWriteFile/safeAppendFile统一处理~展开与父目录创建,避免各处重复实现带来的不一致
三道防线如何协同工作
把上面内容串起来,就是 OpenDirectory 的完整安全模型:
| 阶段 | 防护机制 | 关键文件 |
|---|---|---|
| 提交(PR) | 危险扩展名拦截 + 危险命令模式扫描 + AI/人工审查 | scripts/validate-pr.ts、.github/workflows/pr-validation.yml |
| 安装 | 路径边界防护,拒绝越出skills/的解析路径 | packages/cli/src/install-core.ts |
| 卸载 | 路径边界防护,拒绝删除目录外文件 | packages/cli/src/uninstall-core.ts |
| 更新 | 边界防护 + 备份回滚 + 原子写入 | packages/cli/src/update-core.ts、packages/cli/src/manifest.ts |
| 运行时 | 失败返回结构化错误对象而非崩溃,便于上层提示 | packages/cli/src/fs-adapters.ts |
这套设计给"开放"留下了空间,同时给"安全"设了硬边界:扫描负责在入口过滤恶意内容,边界防护负责在运行时锁死写入范围,回滚与原子写负责让每次失败都有退路。对新手用户而言,这意味着只需一条npx命令,就能在受保护的沙箱式目录里放心安装 Skill。
快速上手
# 交互式浏览、搜索并安装(推荐) npx "@opendirectory.dev/skills" # 或直接安装指定技能 npx "@opendirectory.dev/skills" install <skill-name> --target claude支持 Claude、Codex、Gemini CLI、OpenCode 等 7 类 Agent 目标,--target参数大小写不敏感。想深入了解 CLI 全部命令与 Agent 安装位置表,可参阅 packages/cli/README.md。
【免费下载链接】opendirectory
AI Agent Skills built for Founders who hate Marketing
相关推荐
终极恶意代码防护指南:Bytecode-Viewer安全扫描功能全解析
终极恶意代码防护指南:Bytecode Viewer安全扫描功能全解析 Bytecode Viewer作为一款强大的Java 8+ Jar及Android AP
逆向工程开发工具静态分析桌面应用如何使用Vundle.vim打造安全高效的Vim插件管理系统
如何使用Vundle.vim打造安全高效的Vim插件管理系统 Vundle.vim是一款专为Vim设计的插件管理器,它能够帮助用户轻松管理Vim插件,包括安装、
开发工具插件系统代码编辑器Magento恶意软件扫描器:保护你的电商网站安全完整指南
Magento恶意软件扫描器:保护你的电商网站安全完整指南 在当今数字化的商业环境中,Magento作为最受欢迎的电商平台之一,面临着日益严峻的网络安全威胁。M
应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考