首页
/ OpenCode 安全机制详解:威胁模型、服务器认证配置与安全漏洞报告流程

OpenCode 安全机制详解:威胁模型、服务器认证配置与安全漏洞报告流程

2026-09-06 17:43:54作者:冯梦姬Eddie

OpenCode(开源编码智能体)把 Agent 直接放进了本地系统环境——它可以执行 shell、读写文件、访问网络,因此“它的安全边界在哪里”是使用和生产部署前必须弄清的问题。本文以仓库根目录的 SECURITY.md 为主体,完整还原其威胁模型(Threat Model)与“范围之外”清单,并结合 packages/server/src/auth.tsserve 命令实现 等源码,讲清楚服务器模式的 OPENCODE_SERVER_PASSWORD 认证机制如何落地,最后给出安全漏洞的负责任披露流程与升级路径。

一、安全报告的硬性前提:不接受 AI 生成的报告

SECURITY.md 开头用 "IMPORTANT" 明确划定了一条红线:项目不接受 AI 生成的安全报告。原因很直接——这类报告数量巨大,团队没有资源逐一审查;若提交此类报告,将导致提交者被自动禁止参与项目。这条规则本身也提示了研究者在复现与验证漏洞时的纪律:报告中必须包含人工完成的最小复现步骤与真实危害分析,而非大模型批量扫描产出的低置信度列表。

二、威胁模型:权限系统不是沙箱,这是最重要的设计声明

2.1 总体定位

SECURITY.md 的威胁模型概览指出:OpenCode 是一个运行在用户本机的 AI 编码助手,其 Agent 系统拥有强大工具——shell 执行、文件操作和网页访问。正因工具能力接近“本机用户权限”,文档随后给出了全文最关键的声明:

OpenCode 不会对 Agent 做沙箱隔离。权限系统(permission system)的定位是 UX 功能:在 Agent 执行命令、写文件等动作前提示用户确认,帮助用户保持对 Agent 行为的知情;它并非为安全隔离而设计

如果需要对 LLM 驱动的操作做真正的隔离,官方给出的建议是:把 OpenCode 放进 Docker 容器或虚拟机中运行

2.2 从源码看权限系统到底在做什么

权限系统的实现位于 packages/core/src/permission.ts。从源码结构看,其核心对象包括:

  • Request / Reply:权限请求与用户答复的结构定义;
  • AskResult:一次权限询问的结果;
  • 答复取值包含一次性("once" 语义)与持久化("always")两类——源码中当用户选择 always 时,会把该请求关联的 save 规则写入持久层(持久化存储分别由 packages/core/src/permission/saved.tspackages/core/src/permission/sql.ts 承担)。

这段实现与 SECURITY.md 的声明互为印证:权限系统做的事情是“拦截动作 → 询问用户 → 记录用户偏好”,整条链路依赖用户在场并作出选择,它没有任何机制阻止一个已获得权限的进程去访问本机资源。这正是“UX 特性而非安全边界”这句话的工程含义,也是威胁模型中“沙箱逃逸(Sandbox escapes)不属于安全漏洞”这一条的范围依据。

三、服务器模式:opt-in 的 HTTP 服务与 Basic 认证

3.1 文档声明的认证要求

SECURITY.md 对 Server Mode 的表述可以归纳为三点:

  1. 服务器模式是 opt-in(用户主动开启)的,默认不启用;
  2. 启用后应当设置环境变量 OPENCODE_SERVER_PASSWORD,以要求 HTTP Basic 认证
  3. 不设置该变量时,服务器将在未认证状态下运行(并打印警告)——而“如何保护这台服务器”是最终用户的责任,服务器一旦启用,其对外提供的任何功能本身都不构成安全漏洞。

3.2 认证逻辑的源码印证

认证配置与校验集中在 packages/server/src/auth.ts,其中 ServerAuth 模块的关键实现与文档声明完全对应:

  • 配置读取Config 服务从环境变量读取 OPENCODE_SERVER_PASSWORD(可选)与 OPENCODE_SERVER_USERNAME(默认值 "opencode"),即“用户名默认 opencode、可覆盖”的行为来源于此;
  • 是否需要认证required(config) 判断 password 是否被设置且非空字符串;
  • 凭证校验authorized(credentials, config) 逐字段比对用户名与密码(密码以 Redacted 类型承载,避免在类型层面暴露明文语义);
  • 客户端构造请求头header(credentials) / headers(credentials)username:password 编码为 Authorization: Basic base64(...) 请求头,供 opencode attach 等客户端连接受保护的服务器。

3.3 未设置密码时的警告行为

opencode serve 命令的实现在 packages/opencode/src/cli/cmd/serve.ts。启动 handler 中有如下检查:

if (!Flag.OPENCODE_SERVER_PASSWORD) {
  console.log("Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.")
}

也就是说,警告是打印在日志/终端里、而不是阻止启动——服务器照常监听(源码随后调用 Server.listen(opts) 并输出 opencode server listening on http://host:port)。这与 SECURITY.md “Without this, the server runs unauthenticated (with a warning)” 的表述逐字对应。该环境变量经 packages/core/src/flag/flag.ts 统一读取(OPENCODE_SERVER_PASSWORD: process.env["OPENCODE_SERVER_PASSWORD"]),供 CLI 各命令共用。

仓库内的中文文档 server.mdx 同样给出了可操作的用法示例,认证配置适用于 opencode serveopencode web 两个命令:

OPENCODE_SERVER_PASSWORD=your-password opencode serve

3.4 服务器模式的实践建议

结合上述声明与实现,可以给出三条落地做法:

  • 只在本机、仅自己使用时:保持 opt-in 默认状态即可,不启用服务器;
  • 需要对外提供服务/多端接入时:务必设置 OPENCODE_SERVER_PASSWORD(并视需要设置 OPENCODE_SERVER_USERNAME),同时通过防火墙限制监听地址与来源,Basic 认证只应作为第一道门,不应替代网络层隔离;
  • 需要与不信任内容/代码交互时:按威胁模型的建议,把整个 OpenCode 放进 Docker 容器或 VM,用操作系统级边界替代权限系统。

四、明确划出“范围之外”的类别

SECURITY.md 用一张表把五类情形声明为安全报告范围之外(Out of Scope)。这是理解该项目安全边界时最有信息量的部分,逐条继承如下:

类别 官方给出的理由
Server access when opted-in(主动开启服务器后的访问) 既然你启用了服务器模式,API 被访问就是预期行为
Sandbox escapes(沙箱逃逸) 权限系统不是沙箱(见上文威胁模型声明)
LLM provider data handling(LLM 供应商的数据处理) 发送给你所配置 LLM 供应商的数据,由该供应商自身的政策管辖
MCP server behavior(MCP 服务器行为) 你自行配置的外部 MCP 服务器在项目信任边界之外
Malicious config files(恶意配置文件) 配置由用户自己控制,篡改它不构成攻击向量

这张表的隐含逻辑是:OpenCode 的信任边界锚定在“用户自己的机器、用户自己的配置、用户主动启用的功能”之内。把边界内的问题(例如服务器未设密码时暴露 API)与边界外的行为(例如你自己配置了一个不可信的 MCP 服务器)区分开,是撰写高质量安全报告的前置功课。

五、安全漏洞的报告与升级路径

SECURITY.md 的 "Reporting Security Issues" 部分定义了负责任披露(responsible disclosure)流程:

  1. 提交渠道:通过 GitHub 仓库的 Security Advisory 入口("Report a Vulnerability" 标签页)提交报告,而不是公开 Issue;
  2. 响应承诺:团队会对报告给出回复,说明处理流程中的下一步;在首次回复之后,安全团队会持续同步修复与公告的进展,并可能请求补充信息或提供进一步指导;
  3. 升级路径(Escalation):如果报告提交后 6 个工作日内没有收到确认(acknowledgement),可以发送邮件至 security@anoma.ly 进行升级。

对报告人而言,结合第一节的硬性前提,一份可被受理的报告应满足:人工完成复现与危害分析、问题落在“范围之内”(不属于上表五类)、通过私密的 Advisory 渠道提交,并在 6 个工作日未获响应时走邮件升级。

六、小结

SECURITY.md 的声明与仓库实现对照,OpenCode 的安全模型可以概括为三层:

  • 本地 Agent 层:权限系统提供“事前确认 + 偏好记忆”(见 permission.ts 的 Reply 持久化逻辑),但明确不承诺隔离,强隔离请用容器/VM;
  • 服务器层OPENCODE_SERVER_PASSWORD 开启 HTTP Basic 认证(auth.tsrequired/authorized/header),未设置则未认证运行并给出警告(serve.ts),安全责任在使用者;
  • 披露层:拒绝 AI 生成报告、私密的 Security Advisory 渠道、6 个工作日的确认窗口与 security@anoma.ly 升级邮箱,构成完整的漏洞报告闭环。

理解这三层边界后,无论是本地日常使用、团队共享一台服务器,还是撰写安全报告,都能据此作出与项目设计意图一致的选择。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388