人工智能AI 应用桌面应用AI AgentMCP 服务AI 技能【免费下载链接】genofficeFree, open-source AI Office suite: Docs, Sheets, Slides, PDF, Markdown and HTML editors with a built-in AI agent, plus a genoffice CLI and agent skill so Claude Code, Codex and Cursor can create and edit real .docx/.xlsx/.pptx files locally. Bring your own key. macOS, Windows Linux.项目地址https://gitcode.com/gh_mirrors/ge/genoffice点击查看免费下载GenOffice 是一款开源的 AI 办公套件内置 Docs、Sheets、Slides、PDF、Markdown 与 HTML 编辑器以及内嵌 AI Agent。由于 AI 生成的内容布局脚本、HTML、外部链接、IPC 消息会直接进入渲染进程与主进程的处理链路官方在 SECURITY.md 中建立了一套“纵深防御 能力最小化”的安全模型。本文以该文档为骨架结合仓库源码逐层拆解其漏洞报告流程、进程安全基线、外部链接统一出口以及两个核心威胁模型——AI 生成布局脚本的解释器沙箱与 AI 生成 HTML 的隔离导出窗口帮助读者理解这套体系如何在不牺牲 AI 能力的前提下封堵渲染进程攻击面。漏洞报告流程私密上报72 小时响应SECURITY.md 对安全问题处理方式有明确约定所有疑似漏洞必须通过 GitHub 的private vulnerability reporting私有漏洞报告功能私密提交禁止在公开 issue 中讨论安全问题项目方承诺在72 小时内确认收到的报告报告提交入口位于仓库的安全咨询页面任何安全研究人员、用户或下游集成方都应遵循这一流程避免漏洞在修复前被公开扩散。这一“私有上报、限期确认”的流程是整套安全工程的外部收口内部再多的加固手段也需要一个受控的反馈通道来持续发现边界绕过例如本文后面提到的“布局脚本越权触达”类问题。进程安全基线每个窗口都启用完整渲染器锁定GenOffice 的架构决定了其渲染进程是安全边界的第一道防线每个应用docs、sheets、slides、pdf、markdown、shell、updater都会打开独立的文档窗口或标签页其中加载的既有人工编辑的内容也有 AI 生成的内容。因此 SECURITY.md 规定所有窗口统一启用完整的 Electron 渲染器锁定contextIsolation: true—— 渲染进程与 preload 暴露的 API 之间隔离上下文nodeIntegration: false—— 渲染进程无法直接访问 Node.js 能力sandbox: true—— 渲染进程运行在 OS 级沙箱中。以 docs-main.ts 为例其 BrowserWindow 配置明确写入了上述三项html-main.ts、markdown-main.ts、pdf-main.ts、sheets-main.ts 等应用的主进程代码中同样保持一致。可以推断这一配置是各应用共享的工程基线而非个别窗口的特殊处理。在渲染器锁定之外主进程还承担了两类集中管控1. 类型化、校验过的 IPC 通道。渲染进程只能通过类型化、经过校验的 IPC 通道触达主进程且 payload 会在主进程侧做 schema 校验其中sheets 应用在端到端链路上使用 zod进行校验。这意味着即使某个渲染进程被攻破其能够调用的主进程能力也被限制在已注册、已验证的通道集合内无法通过任意消息驱动任意主进程功能。2. 全应用导航锁定。navigation-guard.ts 通过web-contents-created为每一个 webContents 注册两类默认拦截will-navigate中任何与当前 URL 不一致的全页导航都会被preventDefault正常运行时渲染进程是只加载一次的本地 SPA全页导航只可能来自恶意文档内容或 AI 生成的标记同时为window.open安装默认拒绝deny的处理器。个别应用docs/slides/pdf会针对特定 webContents 用safeExternalUrl替换该默认处理器仅放行白名单协议的外部链接。外部链接统一出口safeExternalUrl协议白名单SECURITY.md 强调每一次shell.openExternal调用都必须经过单一共享门禁即genoffice/electron-utils中的safeExternalUrl。其实现位于 safe-external-url.ts输入必须是字符串否则直接返回null使用 WHATWGURL解析器解析失败即拒绝协议必须命中白名单默认仅http:/https:PDF 的链接批注场景可额外通过allowedProtocols选项放行mailto:返回的是trim 后的原文而不是解析后的对象——因为 WHATWG 解析器会静默剥掉首尾空白若校验时用解析结果、打开时用原始输入shell.openExternal可能拿到一个校验时能通过但实际无法打开的空壳 URL。因此file:、javascript:、smb:等自定义协议以及httpx:这类前缀伪装 URL 一律被拒绝。配套测试 safe-external-url.test.ts 覆盖了非字符串输入、畸形 URL、危险协议、自定义白名单与空白 trim 等场景例如file:///etc/passwd、javascript:alert(1)、smb://server/share均被断言为null。从调用面看docs-main.ts、slides-main.ts、pdf-main.ts、markdown-main.ts 等主进程文件以及渲染侧如 export-links.ts、SlideShowView.tsx都引用了这一工具印证了“单一共享门禁”的说法——任何外部跳转都必须先过这道协议白名单。凭据安全不硬编码 API Key走登录账户代理SECURITY.md 还明确了 AI 场景下的凭据策略任何 API Key 都不允许硬编码进仓库AI 请求默认通过已登录账户代理发出用户自带 KeyBring Your Own Key 模式时Key 只存放于OS 级别的设置存储system-level settings store不会落入文档或普通配置文件。这一设计将“密钥泄露”从代码仓库层面整体移除把风险收敛到系统凭据存储这一标准 OS 边界上同时保留了用户自带 Key 的灵活性。威胁模型一AI 生成的幻灯片布局脚本为什么需要解释器而不是evalSlides 的 AI 通过生成一段“小脚本”来调整版式。关键安全决策是这段源码看起来像 JavaScript但绝不会以可执行源码的形式交给eval、Function、VM 上下文、worker 或 JavaScript 引擎。它由Acorn 解析成 AST再由一个受限的 AST 解释器执行实现位于 layout-script-interpreter.ts。其文件头注释明确写道“Parse and execute the layout DSL without invoking JavaScript”解析并执行布局 DSL但不调用 JavaScript——这是整个威胁模型的根基把“模型输出”和“可执行代码”之间的一切动态求值通路全部切断。脚本按设计可以做什么SECURITY.md 给出了明确的能力清单读取els/canvas的无原型 JSON 副本不是宿主对象无法借此访问原型链执行有上限的算术与流程控制Math辅助函数、数组/字符串/正则方法白名单调用 8 个编辑原语setBox、moveBy、resizeBy、setText、setStyle、setFill、setStroke、log。每个编辑原语都会校验参数元素是否存在、只读标志、数值是否有限、颜色是否为十六进制格式并且只把操作写入一个op 缓冲区该缓冲区最终通过与手工编辑完全相同的命令管线应用。也就是说AI 脚本对版式的任何改动都走正规编辑流程不存在绕过校验的“快车道”。以 layout-script.ts 为例setFill要求颜色必须是#RRGGBB或none否则抛错setStroke要求color为#RRGGBB、widthPt必须为正的有限数值log有 50 条的上限logs.length 50时静默丢弃。而 layout-script.ts 中解释器一旦抛错整个调用的返回结果是{ ops: [], edits: [], logs, error: msg }——所有已缓冲的操作被整体丢弃绝不允许“执行到一半的脏状态”进入文档。解释器边界五条硬约束SECURITY.md 定义了五层边界逐一对应到源码实现1. 标识符只在解释器自有的词法作用域内解析。layout-script-interpreter.ts 的Scope类维护valuesMap 与父作用域链get未命中时直接抛Unknown identifier ... Only the documented layout-script API is available。根作用域root只注入els、canvas的克隆副本、8 个编辑原语、Math/Number/String/Boolean/Object/Array/JSON的白名单辅助。没有环境全局变量、没有模块加载器、没有 DOM、没有网络、没有 IPC 桥、没有定时器、没有 process API、没有任何动态代码原语。2. 属性读取按值类型分派。getMemberlayout-script-interpreter.ts只对以下类型放行数组length、数字下标、约 16 个方法的显式白名单、字符串length、下标及includes/startsWith/split等白名单方法、有界正则对象仅test、Builtin的显式members、以及无原型的普通数据对象只读自有字段。其余一切访问包括计算属性名解析到不允许的方法都会抛错。关键点在于宿主原型和函数属性永远不会被遍历——即使脚本用constructor、__proto__或任意计算属性名去探测也拿不到宿主对象。3. 调用只接受解释器创建的函数或显式内建函数。invokelayout-script-interpreter.ts只认两类值Builtin或ScriptFunction否则抛Only documented functions and safe collection methods can be called。宿主函数无法通过构造器/原型链被“具象化”represented自然也就无法被脚本调用。cloneDatalayout-script-interpreter.ts会把进入编辑原语的输入与返回值递归复制成无原型、JSON 化的数据且拒绝非有限数字与超深嵌套。4. 错误即回滚日志有上限。如前所述任何异常都丢弃全部缓冲操作log日志上限 50 条防止脚本用日志轰炸界面。5. 执行有步数与调用深度上限。常量定义在 layout-script-interpreter.ts常量值作用MAX_STEPS25 000语句/表达式总步数上限拦截死循环与失控递归MAX_CALL_DEPTH64调用深度上限配合步数限制兜底MAX_COLLECTION_SIZE10 000数组/集合大小上限防止内存膨胀其中ticklayout-script-interpreter.ts在每步执行前累加并检查MAX_STEPS超限时报出带行号的错误。正则有独立预算。布局脚本支持正则字面量但绝不让它落到原生引擎——因为原生匹配发生在解释器步数记账之外灾难性回溯catastrophic backtracking的正则会绕过步数限制卡死渲染进程。因此仓库实现了自有的有界正则引擎bounded-regex.ts把正则先编译成自己的 AST字面量、字符类、分组、分支、量词、锚点、i/m/s标志再由带预算的匹配器执行常量值MAX_PATTERN_LENGTH500 字符MAX_REPEAT_COUNT1000 次重复MAX_MATCH_STEPS1 000 000 步MAX_MATCH_DEPTH2000 层它显式拒绝反向引用、命名反向引用、Unicode 属性转义、lookahead/lookbehind 等可能引入复杂回溯的语法unavailable(...)直接抛错每次匹配步进都扣减budget超限抛Layout script regular expression exceeded its execution budget。这就保证了即使恶意构造最坏情形的模式也无法在预算之外卡住渲染进程。边界之外渲染器沙箱只是兜底SECURITY.md 特别强调了一个容易被误解的点Electron 渲染器沙箱在这里只是纵深防御defense in depth并不是布局脚本的安全边界。设计目标是把问题消灭在更前面——布局脚本在解释器模型里从一开始就无法获得渲染进程的能力网络、存储、IPC、主进程访问。文档呼吁如果你能找到一条路径让布局脚本触达注入原语之外的东西网络、存储、按设计不可达的 IPC 通道或主进程那就是一个值得上报的漏洞。这正是本文开头所述漏洞报告流程与威胁模型之间的闭环关系。威胁模型二渲染 AI 生成的 HTML幻灯片导出Slides 的HTML-to-pptx 导出管线需要在隐藏的BrowserWindow中渲染 AI 生成的 HTML。SECURITY.md 对此窗口采取“视同敌对内容”的处置完整渲染器锁定sandbox: true、contextIsolation: true、nodeIntegration: false无 preload 脚本、无 IPC 面——该窗口不暴露任何 IPC 通道主进程是它的唯一驱动方主进程仅通过executeJavaScript驱动其执行窗口在watchdog 超时机制下被销毁防止渲染卡死影响主流程。与之相呼应的代码证据遍布各应用例如 pdf-main.ts、docs-main.ts、html-main.ts、markdown-main.ts、sheets-main.ts 中都存在new BrowserWindow({ show: false, webPreferences: { sandbox: true, javascript: false } })的隐藏窗口模式可见“无脚本、无沙箱逃逸面”的隐藏窗口是各应用处理不可信内容导出、打印、渲染时的统一做法。也就是说即使 AI 生成的 HTML 里夹带了恶意脚本或试图导航到危险 URL它也被限定在一个没有 preload、没有 IPC、有 watchdog 的隔离窗口中无法触达应用数据与主进程。范围外Out of Scope声明SECURITY.md 明确了以下两类问题不在本仓库安全承诺之内云端 AI 服务本客户端所对接的云 AI 服务独立运营不在本仓库范围内相关问题应走服务提供方的渠道上报需要“机器已被攻破”前提的漏洞包括本地开发特意保留的环境变量覆盖点GSK_CLI_PATH与XLSX_SIDECAR_PATH。设置这些变量需要控制进程环境而这本身就等价于在该机器上执行代码——因此不将其视为本应用引入的漏洞。理解这条边界很重要它把安全承诺严格限定在“应用代码自身”这一层避免把供应链、宿主系统与云服务的问题混入本仓库的漏洞管理流程。总结三层防御能力最小化优先纵观 SECURITY.md 与仓库实现GenOffice 的安全模型可以归纳为三个层次进程层所有窗口统一contextIsolation/nodeIntegration: false/sandbox配合导航锁定与默认拒绝的window.open数据层IPC 全链路类型化校验sheets 端到端 zod、外部链接过safeExternalUrl协议白名单、API Key 不进仓库只进 OS 凭据存储AI 内容层AI 布局脚本走 Acorn AST 受限解释器无eval/Function/VM、有步数与正则预算、错误即回滚AI 生成的 HTML 只在无 preload、无 IPC、受 watchdog 保护的隐藏窗口渲染。整套体系的核心哲学是能力最小化不是“在沙箱里运行不可信代码再祈祷它不逃逸”而是让不可信代码在模型层就无法表达宿主能力。对于任何想要在自己的 Electron AI 产品中安全地引入“模型生成代码/标记”能力的开发者SECURITY.md、layout-script-interpreter.ts、bounded-regex.ts、safe-external-url.ts 与 navigation-guard.ts 构成了一份可直接对照学习的参考实现。赞分享人工智能AI 应用桌面应用AI AgentMCP 服务AI 技能【免费下载链接】genofficeFree, open-source AI Office suite: Docs, Sheets, Slides, PDF, Markdown and HTML editors with a built-in AI agent, plus a genoffice CLI and agent skill so Claude Code, Codex and Cursor can create and edit real .docx/.xlsx/.pptx files locally. Bring your own key. macOS, Windows Linux.项目地址https://gitcode.com/gh_mirrors/ge/genoffice点击查看免费下载相关推荐drawio-desktop沙箱模式渲染进程安全隔离技术drawio desktop沙箱模式渲染进程安全隔离技术 引言Electron应用的安全挑战 在现代桌面应用开发中Electron框架凭借其跨平台能力和W桌面应用图形学终极指南如何利用Tampermonkey安全沙箱保护你的浏览器环境终极指南如何利用Tampermonkey安全沙箱保护你的浏览器环境 Tampermonkey作为最受欢迎的用户脚本管理器拥有超过1000万用户支持Chro前端插件系统OpenManus DockerSandbox 深度解析用 Docker 容器为 AI Agent 代码执行构建安全隔离沙箱OpenManus DockerSandbox 深度解析用 Docker 容器为 AI Agent 代码执行构建安全隔离沙箱 本文围绕 OpenManus 教人工智能AI 应用AI Agent上一篇终极指南OpenPose模型跨框架部署的完整解决方案与最佳实践下一篇终极本地化部署指南PPTAgent离线模式完全掌控手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
