- 人工智能
- AI Agent
- 自主智能体
- 桌面应用
- MCP Clients
【免费下载链接】Kun
Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.
本文以仓库根目录的 SECURITY.md 为骨架,系统讲解 Kun(Local-first AI Agent 工作台)的安全披露流程、受支持版本策略与五大安全关注范围,并结合仓库源码深入剖析凭证加密、Electron 沙箱加固、POSIX 权限收敛等底层实现。读完本文,你将掌握 Kun 的安全报告机制,理解 OAuth 令牌、密钥文件等敏感数据在磁盘上的加密存储原理,并学会从源码与测试两个层面验证项目的安全边界。
一、SECURITY.md 的定位:披露机制 + 安全边界声明
SECURITY.md 是 Kun 面向安全研究者与用户的公开安全策略文档,同时仓库提供了对应的中文版 SECURITY.zh-CN.md。它承担两重职责:一是定义漏洞披露流程(支持的版本、报告渠道、响应时间承诺),二是划定安全范围(哪些问题需要私下报告、哪些属于核心防护目标)。这两部分共同构成项目安全的"对外契约",而契约背后的实现,则散落在kun/src/security/、src/main/browser-security/等源码目录中,下文会逐一对应展开。
文档明确要求:安全敏感缺陷不得通过公开 Issue 报告,必须走私密渠道;在修复或缓解措施可用、维护者获得合理响应时间之前,不得公开披露。这是所有漏洞报告类安全策略的通用基线,也与仓库中多处"fail-closed(故障关闭)"的实现哲学一致——不确定时不冒险,宁可拒绝操作也不破坏既有数据。
二、支持的版本:最新维护分支 + 最新发布版本
SECURITY.md 声明:安全修复通常应用于默认分支上最新维护的代码,并在实际可行时同步到最新发布版本;旧版本可能无法收到补丁。
这与仓库的发布管理实践吻合:仓库根目录的 release/ 目录按release-vX.Y.Z.md组织了大量版本说明(例如release-v0.2.0.md至release-v0.3.11.md),kun/src/version.ts 维护运行时版本号。这意味着:
- 如果你在生产环境使用 Kun,应优先跟随最新发布版本;
- 安全研究者应以默认分支(main)的最新提交为评估基线;
- 历史版本的安全修复不保证回填,升级是获得修复的主要途径。
三、报告漏洞:私密渠道与必备要素
3.1 报告渠道
| 渠道 | 说明 |
|---|---|
| 邮件 | zhongxingyuemail@gmail.com |
| GitHub Security Advisories | 若仓库启用了私有漏洞报告流程,可走该入口 |
文档同时要求:请勿针对安全敏感问题公开 GitHub Issue,避免漏洞细节在修复前被滥用。
3.2 建议附带的报告要素
SECURITY.md 明确列出的要素如下,逐条附上"为什么有用"的解读:
- 问题清晰描述——帮助维护者快速定位缺陷类型(是逻辑错误、越权、还是信息泄露);
- 受影响的版本、commit 或 release tag——仓库以 release/ 下的版本号和 Git 提交为追踪单位,精确到版本/提交可大幅加速分诊;
- 复现步骤或概念证明(PoC)——可复现性是分诊与回归测试的前提;
- 影响评估——如是否可远程触发、是否需要认证、影响的数据范围等;
- 任何建议的缓解措施——包括临时规避方案与修复思路。
这些要素对应源码仓库中的实际测试风格:kun/src/security/secret-store.test.ts中的每个用例都围绕一个明确场景展开(如"OS credential store disabled 时仍可加密/解密"),报告人若能提供同样的最小化场景,维护者即可直接映射到测试矩阵。
四、响应承诺:3 个工作日确认
SECURITY.md 给出了明确的响应时间线:
- 3 个工作日内确认新报告;
- 确认问题是否在范围内(in scope);
- 分诊(triage)过程中持续告知报告人进展;
- 尽快负责任地发布修复或缓解措施。
五、安全范围:五大风险类别与仓库实现对照
SECURITY.md 列出的报告范围,恰好与仓库源码中的安全实现一一对应。下表给出范围条目与实现证据的映射,随后逐项展开。
| 范围条目 | 对应实现证据 |
|---|---|
| 远程代码执行 / 权限提升 | Electron 渲染层加固:web-contents-hardening.ts |
| 不安全文件访问 / 沙箱绕过 | POSIX 权限收敛:posix-permissions.ts、Manager 原子 JSON 路径权威校验 |
| 凭证、令牌、密钥泄露 | 密钥加密存储:secret-store.ts、secret-encryptor.ts |
| 更新程序 / 打包 / 发布完整性 | 发布校验脚本:scripts/verify-public-release.mjs、scripts/verify-windows-signing.ps1 |
| 捆绑本地服务 / 集成路径 | Browser-use 审计日志、扩展宿主隔离等 |
5.1 远程代码执行与权限提升:渲染层沙箱
Kun 基于 Electron 构建桌面 GUI,其安全边界的第一道防线是渲染进程。src/main/browser-security/web-contents-hardening.ts提供的hardenedRemoteWebPreferences集中定义了远程内容的默认 WebPreferences:
nodeIntegration: false, nodeIntegrationInWorker: false, nodeIntegrationInSubFrames: false, contextIsolation: true, sandbox: true, webSecurity: true, allowRunningInsecureContent: false, webviewTag: false, navigateOnDragDrop: false, safeDialogs: true, disableDialogs: true, autoplayPolicy: 'document-user-activation-required', spellcheck: false要点解读:
sandbox: true+contextIsolation: true:渲染进程运行在 Chromium 沙箱中,且无法直接访问 Node/Electron 能力,这是阻断"渲染层 → 主进程 RCE"的关键组合;nodeIntegration全系关闭:包括 Worker 与 SubFrame,杜绝任何旁路注入路径;webviewTag: false:禁用易出问题的<webview>标签;disableDialogs: true:禁止远程内容弹出对话框,防钓鱼与自动确认攻击。
同一文件中的hardenRemoteSession则实现默认拒绝的权限模型:
target.setPermissionRequestHandler((_contents, _permission, callback) => callback(false)) target.setPermissionCheckHandler(() => false) target.setDevicePermissionHandler(() => false) target.on('will-download', (event) => event.preventDefault())即:所有权限请求一律拒绝、下载一律拦截。对应的 web-contents-hardening.test.ts 用于验证这些默认值不会被后续修改破坏。
5.2 不安全文件访问与沙箱绕过:POSIX 权限收敛
kun/src/security/posix-permissions.ts提供跨平台感知的权限收紧工具:
export function shouldApplyPosixMode(platform: NodeJS.Platform = process.platform): boolean { return platform !== 'win32' } export async function applyPosixMode(path: string, mode: number): Promise<void> { if (!shouldApplyPosixMode()) return await chmod(path, mode) }由于 Windows ACL 并不实现 POSIX 权限位,该模块在win32上自动跳过,避免误用;在 macOS/Linux 上则对敏感文件强制0600/0700权限。它被多个子系统复用,例如src/main/browser-use/browser-use-audit-log.ts通过import { applyPosixMode } from '../../../kun/src/security/posix-permissions.js'对审计日志施加限制性权限——这印证了权限工具是"共享安全基础设施",而非单一模块的私有实现。
此外,凭证写入过程对密钥文件目录使用0o700、文件使用0o600(见下文),并依赖AtomicJsonFile+ Manager 路径权威校验(assertManagerAtomicJsonPath)确保密钥/租约文件只能落在 Manager 授权目录内,防止路径穿越类越权写入。
5.3 凭证、令牌与密钥泄露:AES-256-GCM 加密存储
这是 SECURITY.md 范围中实现最深的一环。Kun 的凭证存储位于 secret-store.ts,其文件头注释直接点明设计动机:"OAuth tokens must not be plaintext"(OAuth 令牌不得以明文存储)。
5.3.1 加密算法与信封格式
secret-encryptor.ts 使用AES-256-GCM(32 字节密钥、12 字节随机 IV),并支持 AAD(附加认证数据)绑定,密文信封格式为:
enc:v1:<iv base64>:<authTag base64>:<ciphertext base64>encrypt()每次生成全新随机 IV,decrypt()先校验信封前缀,再校验认证标签,任何篡改都会被 GCM 的完整性校验拒绝。createCompatibleEncryptor还实现了"主密钥写、双密钥读"的兼容模式,用于系统密钥与临时回退密钥并存时期的数据平滑迁移。
5.3.2 密钥来源三级优先级
createSecretEncryptor(kun/src/security/secret-store.ts)按如下优先级解析 32 字节主密钥:
- macOS Keychain:通过
security find-generic-password(service=kun-secret-key,account=kun)读取,security add-generic-password写入; - Linux Secret Service:通过
secret-tool lookup/store读写同一 service/account; - Windows DPAPI:用 PowerShell
ProtectedData以CurrentUser 作用域对 AES 密钥进行 DPAPI 包裹,将dpapi:v1:前缀的受保护 blob 写入密钥文件——即使密钥文件被拷走,其他用户或机器也无法解密; - 最终回退:生成随机密钥写入0600 权限的密钥文件(目录 0700)。
关键细节:密钥内容一律通过stdin 喂给系统凭证助手,绝不进入 argv,避免密钥出现在进程列表(ps)中——对应defaultSecretCommandRunner对spawn(command, args, { shell: false })与child.stdin.end(input)的封装。
5.3.3 故障关闭(fail-closed)策略
secret-store.ts中多处体现了"宁可失败、不可损坏"的 fail-closed 语义,这是安全范围中"凭证泄露"风险的核心防线:
- 查找失败 ≠ 确认缺失:Keychain/Secret Service 查询返回
unavailable(而非确认missing)时,默认拒绝生成新密钥替换,因为旧凭证仍由临时不可读的密钥加密,贸然替换会导致数据永久不可解密(报错文案:refusing to replace the existing Kun encryption key); - 无法读取的 DPAPI 密钥文件:检测到
dpapi:v1:前缀但解密失败时,抛出UnreadableCredentialKeyError(错误码credential_key_unreadable),拒绝用新密钥覆盖旧密文; - 双世代密钥并存:若 Keychain 密钥与回退密钥文件内容不同,则同时保留两者(
createCompatibleEncryptor双读),绝不删除任一代密钥; - 未知凭证状态按加密处理:
hasPersistedSecretKeyMaterial对无法解析的凭证文件一律视为"需要密钥",调用方因此 fail-closed 而非误删。
5.3.4 并发引导的租约协调
多进程(GUI + Runtime + CLI)同时首次启动时,密钥的查找/迁移/引导必须串行。secret-store.ts通过SecretKeyBootstrapLease实现:租约文件为${keyFilePath}.bootstrap-lease.v1.json,schemaVersion 1,租约有效期 30 秒、心跳 5 秒、最长等待 90 秒;租约通过 Manager 的AtomicJsonFileCAS 更新选举唯一引导者,且租约文件本身不含任何密钥材料——密钥只存在于 OS 凭证库或 0600 密钥文件中,Manager 只负责"选出一位执行者"。当租约过期但属主进程仍存活(leaseOwnerIsDefinitelyDead仅以ESRCH判定死亡)时,会拒绝回收租约,防止误杀活进程的密钥引导。
5.3.5 自动化场景的隔离开关
openspec/changes/harden-automation-credential-store-isolation/specs/credential-store-isolation/spec.md定义了一个重要配置:当环境变量KUN_DISABLE_OS_CREDENTIAL_STORE=1(或显式传入disableOsKeychain选项)时,密钥提供者完全不调用操作系统凭证助手(Keychain / Secret Service / DPAPI),改用 0600 密钥文件的加密回退,实现主机凭证设施的"hermetic(密封)隔离"。这一设计同时服务两类场景:
- 自动化测试:单元测试与桌面冒烟测试在初始化前启用隔离,仅使用各自的数据目录,绝不读写宿主用户的凭证库;
- 自动化 Agent 运行:在 CI 或无人值守环境中避免弹出系统密码对话框。
该 spec 还要求官方测试环境在应用初始化前启用隔离、子进程继承隔离设置,与secret-store.test.ts中大量以隔离/回退为前置条件的用例(如OS credential store disabled场景)相互印证。
5.4 更新程序、打包与发布完整性
SECURITY.md 将"updater、packaging 或 release integrity weaknesses"列为报告范围。仓库在 scripts/ 目录准备了完整的发布校验链,例如:
- verify-public-release.mjs:校验公开发布的工件与签名;
- verify-windows-signing.ps1:验证 Windows 签名;
- verify-apple-signing.cjs、mac-notarize.cjs:macOS 签名与公证;
- public-release-download.mjs 与 release.sh:发布下载与流水线执行。
这些脚本证明:发布物的签名、公证与完整性校验是发布流程的强制环节,而非事后检查。
5.5 捆绑本地服务与集成路径
Kun 捆绑了 Browser-use、扩展宿主、本地服务等集成路径,安全范围要求报告其中的漏洞。仓库中的典型加固包括:
- Browser-use 审计日志(browser-use-audit-log.ts):对审计日志施加限制性 POSIX 权限并执行有界轮转,防止日志被篡改或无限增长;
- 不可信内容包裹(untrusted-content.ts):将外部来源内容包裹为
<untrusted-content source="...">标记,并对属性做&、"、<转义,防止注入与混淆,同时保留来源可追踪性; - 扩展宿主:扩展通过隔离的 API 面与主进程交互(见 docs/extensions/ 中的架构与安全文档),默认拒绝越权能力。
六、测试与自动化隔离:如何验证安全边界
仓库为安全实现配备了系统化测试,最典型的是 secret-store.test.ts,覆盖的关键断言包括:
- 密文往返:
encrypt('bearer-token-123')后,序列化 blob不包含明文(expect(blob).not.toContain('bearer-token-123')),且能正确decrypt还原; - AAD 绑定:以
profile-a:credential-a为 AAD 加密的密文,用profile-b:credential-a解密必须抛错; - fail-closed 行为:OS 凭证库不可用且不允许回退引导时,拒绝执行凭证副作用;DPAPI 密钥冲突时报
different credential generations; - 密钥文件隔离:密钥路径位于 Manager 授权目录之外时,在任何凭证副作用发生前即被拒绝;
- 回退密钥文件内容不可泄露:断言密钥文件本身不包含明文机密。
而openspec/changes/harden-automation-credential-store-isolation/下的 spec 则通过WHEN/THEN 场景形式(如"KUN_DISABLE_OS_CREDENTIAL_STORE恰为1时,凭证初始化不执行任何 Keychain/Secret Service/DPAPI 助手")固化了隔离行为的验收标准,与secret-store.ts中environment[DISABLE_OS_CREDENTIAL_STORE_ENV] === '1'的判断逻辑一一对应。
七、给使用者与安全研究者的实践建议
综合 SECURITY.md 与源码实现,可提炼出如下可操作建议:
- 发现疑似漏洞时:不要发公开 Issue,通过 SECURITY.md 中列出的私密渠道报告,并附上"影响版本 + PoC + 影响评估"三要素,可显著缩短分诊周期;
- 升级策略:以最新发布版本为基线(见 release/),旧版本不保证获得安全修复;
- 自动化/CI 场景:设置
KUN_DISABLE_OS_CREDENTIAL_STORE=1隔离宿主凭证库,避免自动化运行触碰真实用户密钥; - 理解凭证边界:无论密钥来自系统钥匙串还是 0600 密钥文件,令牌在磁盘上始终以 AES-256-GCM 密文存储;密钥文件回退是"已文档化、足够安全"的降级路径(密钥文件仅属主可读),并非明文存储;
- 渲染层隔离:远程/不可信内容在 sandbox + contextIsolation + 默认拒绝权限模型的约束下运行,任何试图放宽这些默认值的改动都应在 web-contents-hardening.test.ts 中体现回归测试。
综上,SECURITY.md 不是一份孤立的模板文档:它的每一条范围声明都能在仓库中找到对应的实现与测试证据——从凭证的 AES-256-GCM 加密与三级密钥来源,到 Electron 渲染沙箱与默认拒绝的权限模型,再到发布签名校验与自动化凭证隔离,共同构成了 Kun 从"披露机制"到"纵深防御"的完整安全体系。
- 人工智能
- AI Agent
- 自主智能体
- 桌面应用
- MCP Clients
【免费下载链接】Kun
Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.
相关推荐
NOFX 安全策略与纵深防御实践:密钥保护、漏洞披露与部署加固完全指南
NOFX 安全策略与纵深防御实践:密钥保护、漏洞披露与部署加固完全指南 NOFX 是一套同时管理美股、大宗商品、外汇与加密货币交易的 AI 交易终端,直接持有真
AI Agent金融科技后端前端Lore 安全策略全解读:漏洞报告、披露流程与安全加固实践
Lore 安全策略全解读:漏洞报告、披露流程与安全加固实践 Lore 是一款开源的下一代版本控制系统,其安全策略由维护方 Epic Games 制定并公开在仓库
版本控制后端Open Glean 安全策略与纵深防御架构:漏洞上报、密钥托管与出站请求防护全解读
Open Glean 安全策略与纵深防御架构:漏洞上报、密钥托管与出站请求防护全解读 Open Glean 是一个开源的 AI 知识工作平台,其核心职责包括代用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考