安全模型
octo 是一个单用户、私人使用的 agent。它的服务(octo serve)代表它唯一受信任的操作者执行任意
shell 命令——这是产品设计本身,不是一个漏洞。这一页说明安全边界划在哪里、靠什么保护,
以及哪些是有意留在边界之外的。
- 只有一个用户。 没有账号,没有角色。持有访问密钥的人(或者坐在这台机器前的人)拥有完全控制权, 包括通过聊天执行命令。
- 回环地址是被信任的。 来自
127.0.0.1/::1的请求不需要 key 认证——反正任何已经能在这台机器上 以本地用户身份跑代码的东西,本来就在边界之外了。 - 其他所有地方都需要 key。
octo serve默认绑定127.0.0.1:8088;绑得更宽 (-addr :8088)之后,每一个来自非回环客户端的 API 和 WebSocket 请求都需要 访问密钥。
| 威胁 | 防御手段 |
|---|---|
| 局域网/公网攻击者调用暴露出去的 API | 默认只绑回环地址;非回环请求都要过 256 位访问密钥(常数时间比较) |
恶意网站从你自己的浏览器对 http://localhost:8088 发起 CSRF |
Origin 必须是本地或者在 --cors 白名单里(字面量 * 永远不会被接受);认证 cookie 是 SameSite=Strict |
| DNS rebinding(攻击者的域名解析到 127.0.0.1) | 回环豁免要求 Host 头必须是本地地址 |
| 伪造客户端 IP | 回环豁免判断时完全不看 X-Forwarded-For |
| 上传文件的 XSSI 读取 | 提供的上传文件带 X-Content-Type-Options: nosniff |
IM 渠道(飞书、钉钉、Discord 等)走各自平台的 bot 凭证加上 octo 的聊天/用户绑定单独认证; 这些适配器只发起出站连接,不暴露任何入站 HTTP 路由。
有意不防的东西
Section titled “有意不防的东西”- 本机的恶意进程。 回环流量是被信任的;任何以本地用户身份在同一台机器上运行的恶意软件都能 访问这个 API。如果机器是共享的或者已经被攻破,访问密钥帮不上忙。
- 明文传输。 key 通过 HTTP 的 cookie/header 传输。在不受信任的网络上,请在前面接一层 TLS
(反向代理、
tailscale serve)或者用隧道。 - 暴力破解。 没有锁定机制也没有限流——key 是 256 位
crypto/rand生成的,在线猜测本来就不可行。
解析优先级:octo serve --access-key flag → OCTO_ACCESS_KEY 环境变量 →
~/.octo/config.yml 里的 access_key → 首次启动时自动生成并持久化(权限 0600)。
当绑定地址不是纯回环时,启动会打印一个带 key 的、可以直接打开的 URL;Web UI 会把它存起来,
并从地址栏里去掉。
客户端可以用 Authorization: Bearer <key>、X-Access-Key,或者 octo_access_key cookie 来
提供 key(access_key 查询参数只在 /ws 上生效)。GET /api/health 和 GET /api/version
是仅有的两个免认证路由,且不携带任何机密信息。
要轮换 key:编辑 config.yml 里的 access_key 并重启(或者调用 POST /api/restart)。
octo upgrade(以及 Web UI 的升级按钮)会校验下载的压缩包的 SHA-256,比对同一个 release 的
checksums.txt,两者都通过 GitHub 的 TLS 获取。这能防住传输损坏和镜像篡改——但防不住
一个被攻破的 GitHub 账号发布恶意 release;目前还没有签名层。版本检查(Web 徽标背后那个)是
自动的;安装从来不是自动的,并且和其他所有会修改状态的接口一样,要过访问密钥认证。
报告安全漏洞
Section titled “报告安全漏洞”请提交一个 GitHub 安全公告, 或者私下邮件联系维护者——可利用的漏洞请不要发公开 issue。