Please report suspected vulnerabilities privately via GitHub's private vulnerability reporting for this fork, if enabled. Do not report Opis vulnerabilities to the upstream GenOffice project or open public issues for security reports. The fork maintainer should update this section with a direct contact method and response target before publishing a production release.
All application windows run with the full Electron renderer lockdown:
contextIsolation: true,nodeIntegration: false,sandbox: truefor every document window and tab view (docs, sheets, slides, pdf, markdown, shell, updater).- Renderers reach the main process only through typed, validated IPC channels (payloads are schema-checked in the main process; sheets uses zod end to end).
- Every
shell.openExternalcall goes through a single shared gate (@genoffice/electron-utils→safeExternalUrl) that parses the URL and enforces a protocol allowlist (http/https; pdf link annotations additionally allow mailto).file:,javascript:, and custom schemes are always rejected. - No API keys are hardcoded. AI requests are proxied through the signed-in account by default. The Opis custom-provider feature stores a user-supplied key in the local Electron user-data settings file; it is not an OS keychain or a guarantee of encrypted storage. Users should protect the device, avoid sharing the settings file, and rotate keys if they may have been exposed.
Custom-provider users should assume that prompts and attachments may be sent to the endpoint they configure. They are responsible for selecting a provider whose terms, privacy controls, and data-processing arrangements are suitable for the material they submit.
The slides AI can adjust slide layouts by emitting a small script that is
parsed with Acorn and evaluated by a constrained AST interpreter
(apps/slides/src/renderer/ai/layout-script-interpreter.ts). The source looks
like a small, synchronous subset of JavaScript for model compatibility, but it
is not passed to eval, Function, a VM context, a worker, or the JavaScript
engine as executable source.
What the script can do by design: read prototype-free JSON copies of
els/canvas, perform bounded arithmetic/control flow, use explicitly
implemented string/array/regular-expression/Math helpers, and call
setBox/moveBy/resizeBy/setText/setStyle/setFill/setStroke/log. Every edit
primitive validates its arguments (element existence, read-only flags, finite
numbers, hex colors) and writes only into an op buffer that is applied through
the same command pipeline as manual edits.
Interpreter boundary:
- Identifiers resolve only in interpreter-owned lexical scopes seeded with the documented data and callables. There are no ambient globals, module loader, DOM, network, IPC bridge, timers, process APIs, or dynamic code primitives.
- Property reads are dispatched by value type. Data objects expose own JSON fields only; arrays, strings, and regexes expose a small method allowlist. Host prototypes and function properties are never traversed, including through computed property names.
- Calls accept only interpreter-created functions or explicit builtins. A host function obtained through a constructor/prototype chain cannot be represented.
- Inputs and values crossing into edit primitives are recursively copied as JSON-like, prototype-free data. Errors discard all buffered operations; logs are capped.
- Execution has statement/expression and call-depth limits to bound runaway loops or recursion.
The Electron renderer sandbox remains defense in depth, but it is not the layout-script security boundary. The interpreter is designed so a layout script cannot obtain renderer capabilities in the first place.
If you find a way for a layout script to reach anything beyond the injected primitives (network, storage, IPC channels not reachable by design, or the main process), that is a vulnerability — please report it.
The HTML-to-pptx export pipeline renders AI-generated HTML in a hidden
BrowserWindow. That window is treated as hostile content: full renderer
lockdown (sandbox: true, contextIsolation: true, nodeIntegration: false),
no preload script, no IPC surface — the main process drives it exclusively
through executeJavaScript and destroys it under a watchdog timeout.
- The cloud AI services this client talks to are operated separately and are not part of this repository; issues with them should be reported through the service provider's channels.
- Vulnerabilities that require an already-compromised machine or a modified
binary. This includes the deliberate environment-variable override points
for local development (
GSK_CLI_PATH,XLSX_SIDECAR_PATH): setting them requires control of the process environment, which is equivalent to code execution on the machine.