fix: 修复远程 Skill 宿主文件读取并隔离拉取流程 - #904
Conversation
There was a problem hiding this comment.
Pull request overview
该 PR 针对远程 Skill 安装链路(npx skills 在宿主执行导致的 symlink 解引用风险)做安全修复:通过“来源白名单治理 + 一次性无凭据 Sandbox 执行”的方式,将不可信远程仓库的拉取与目录回流隔离到 Sandbox 中,宿主侧只接收并落盘经校验的普通 bytes,从而阻断 #895 描述的宿主文件读取链路。
Changes:
- 新增并接入
remote_skill_source_policy配置项(PostgreSQLconfig_options),前端在「基本设置」提供精确 hostname 白名单编辑,并同步更新相关文档/变更记录。 - 远程 Skill list / prepare / batch / search 改为在一次性 Provisioner Sandbox 中执行(
inherit_env=False,Kubernetes 禁止自动挂载 ServiceAccount token),并新增 Sandbox → 宿主目录下载的边界校验与限额逻辑。 - 增加/更新单元与集成测试,覆盖白名单、隔离执行、目录回流校验、超时与清理语义。
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/components/SkillSettingsSection.vue | 新增远程来源白名单配置 UI(tags 输入、加载/保存)。 |
| web/src/components/BasicSettingsSection.vue | 在基本设置中挂载 Skill 配置区块。 |
| docs/develop-guides/changelog.md | 记录远程 Skill 来源策略与隔离执行变更。 |
| docs/agents/skills-management.md | 更新远程安装说明:白名单、Sandbox 执行、回流校验与限额。 |
| docs/agents/sandbox-architecture.md | 补充远程 Skill 拉取不继承环境变量与禁用 SA token 的说明。 |
| docker/sandbox_provisioner/app.py | Provisioner 创建 Sandbox 支持 inherit_env,K8s 禁用 SA token 挂载。 |
| backend/test/unit/toolkits/test_install_skill.py | 覆盖从 Sandbox 安装个人 Skill 的下载边界与线程卸载行为。 |
| backend/test/unit/services/test_skill_service.py | 更新远程 skill 准备接口的签名/传参断言。 |
| backend/test/unit/routers/test_skill_router.py | 覆盖 remote list 路由向下传递 db 会话参数。 |
| backend/test/unit/config/test_options.py | 覆盖 remote_skill_source_policy 的默认值、显式空列表与类型校验。 |
| backend/test/unit/backends/test_sandbox_provisioner_config.py | 覆盖 inherit_env 转发、Docker/K8s 禁用环境/SA token。 |
| backend/test/unit/backends/test_sandbox_provisioner_client.py | 覆盖 provisioner client 传递 inherit_env。 |
| backend/test/unit/backends/test_sandbox_download.py | 新增 Sandbox 目录下载的越界/限额/清理语义测试。 |
| backend/test/unit/backends/test_sandbox_backends.py | 覆盖 provider 释放/锁回收、inherit_env 行为与超时传递。 |
| backend/test/unit/agents/skills/test_remote_install.py | 覆盖来源白名单规范化、一次性 Sandbox 执行与回流目录行为。 |
| backend/test/integration/api/test_system_router_api.py | 集成覆盖:remote_skill_source_policy 显式空列表可见与可恢复。 |
| backend/server/routers/skill_router.py | remote list 路由注入 db 并传递到服务层。 |
| backend/package/yuxi/config/options.py | 新增 remote_skill_source_policy 配置项;支持 list[str] 值保留与类型校验。 |
| backend/package/yuxi/agents/toolkits/buildin/install_skill.py | Sandbox 安装路径改用统一的目录下载校验逻辑,并线程卸载避免阻塞事件循环。 |
| backend/package/yuxi/agents/skills/service.py | 远程批量准备接口补充 db 参数传递。 |
| backend/package/yuxi/agents/skills/remote_install.py | 核心改造:白名单规范化校验 + 一次性无凭据 Sandbox 执行 + 目录回流下载。 |
| backend/package/yuxi/agents/backends/sandbox/provisioner_client.py | create 请求新增 inherit_env 字段。 |
| backend/package/yuxi/agents/backends/sandbox/provider.py | 支持 inherit_env;线程锁改 WeakValueDictionary;新增 release 清理缓存。 |
| backend/package/yuxi/agents/backends/sandbox/download.py | 新增 Sandbox 目录下载的路径校验、限额与失败清理实现。 |
| backend/package/yuxi/agents/backends/sandbox/backend.py | Sandbox backend 透传 inherit_env;execute 增加 HTTP 超时选项传递。 |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e2f554421
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
变更描述
本 PR 修复远程 Skill 安装链路中的宿主文件读取风险,关联
xerrors/Yuxi#895,并将实现收敛到清晰、可维护的安全边界。原链路在 API 宿主执行
npx skills。恶意仓库中的符号链接可能被 CLI 解引用,使宿主文件进入 Skill 草稿、安装或导出流程。当前方案只保留两层必要防护:
设计与实现
精确来源白名单
config_options,默认允许github.com和modelscope.cn。owner/repo简写仍受github.com白名单约束,www.github.com不再隐式等同于github.com。白名单负责产品来源治理,不等同于 Sandbox 网络出口防火墙。
一次性无凭据 Sandbox
npx skills add --list、批量准备和搜索统一在一次性 Provisioner Sandbox 中执行。inherit_env=False阻止继承全局sandbox.env和用户 Agent 环境变量。简化后的 Sandbox 回流
download_files()获取普通 bytes。..、根外路径和重复目录。本轮删除了逐级
openat/O_NOFOLLOW、Sandbox 临时文件、SHA-256 校验、原子限长读取、专用 limited-download 响应和执行位恢复。标准文件 API 返回完整 bytes 后才检查实际总大小,因此这里不再承诺传输前内存硬上限、原子 no-follow 或 TOCTOU 防护。该取舍与当前威胁模型一致:远程代码在无凭据 Sandbox 内运行,宿主只校验返回路径并写入普通 bytes。影响范围
现有 Skill 权限、共享范围、草稿协议、冲突改名和批量结果顺序保持不变。
变更类型
测试
自动化验证
115 passed11 passedgit diff --check:通过覆盖范围包括:
inherit_env=False在 backend、provider、client、Docker 和 Kubernetes 的传递。安全边界与非目标
关联与说明
xerrors/Yuxi#895xerrors/Yuxi#855贡献说明
本 PR 使用 Codex 辅助完成。贡献者已人工审阅全部改动,并完成以下验证:
💡 提示:提交前可以运行
make lint和make format检查代码规范。