mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-06 04:52:48 -04:00
* feat(templating): (T1) pluginSandboxEnabled + per-plugin elevated opt-in, centralized gate Introduces the trust-model flip's core logic and wires every untrusted-execution surface to it. - New setting `pluginSandboxEnabled` (default off) that supersedes/absorbs `templateTagSandboxEnabled`: either flag on activates the sandbox, so existing template-tag opt-ins keep working (migration bridge). - New per-plugin `pluginConfig.elevated` escape hatch: a user plugin marked elevated runs in-process with full host access even while the sandbox is on. Widened PluginConfig/PluginConfigMap/Plugin.config. - New pure resolver `common/plugins/sandbox-mode.ts` (isSandboxEnabled / resolvePluginExecutionMode / shouldSandboxPlugin) — the single source of truth replacing the 7 duplicated `templateTagSandboxEnabled && directory !== ''` conditions. Dependency-free so main, the plugin window, and the inso CLI node runtime all share it. Unit-tested (12 cases). - Wired all surfaces to shouldSandboxPlugin: load-time discovery (now per-plugin, so an elevated plugin is nodeRequire-d for live functions), request/response hooks (plugin-window + node runtime), actions, and user template tags. Bundle-tag path reads isSandboxEnabled (bundle stays trusted). No UI yet (next commit); default-off means no behavior change until a flag is toggled. * feat(templating): (T1) Preferences UI — plugin-sandbox toggle + per-plugin elevated + mode indicator - Scripting settings: new "Sandbox all plugin code (experimental)" toggle for pluginSandboxEnabled (data-testid toggle-plugin-sandbox), beside the existing template-tag toggle. - Plugins settings: each user plugin card now shows its resolved execution mode (Sandboxed / Elevated / In-process, data-testid plugin-mode-<name>) and a "Full host access" checkbox (data-testid plugin-elevated-<name>) that writes pluginConfig.<name>.elevated. Mode + toggle read from live settings so they update immediately, before the plugin list reloads. - Widened SerializablePlugin.config to carry the optional `elevated` flag through the bridge. * test(templating): (T1) e2e — pluginSandboxEnabled sandboxes a user plugin; elevating runs it in-process Composes the trust-flip's two user-visible behaviors on one action-probe plugin: - Enabling the new pluginSandboxEnabled toggle (not the legacy template-tag flag) routes the user plugin's action into the sandbox (canary reports ranin-sandboxed). - Toggling "Full host access" in Preferences → Plugins flips the mode indicator to "Elevated" and the same action then runs in-process (marker absent, ranin-mainprocess) — the per-plugin escape hatch. Reuses the sandbox-action-collection.yaml fixture and the established writePlugin/clearPluginToast helpers; adds enablePluginSandbox + setPluginElevated helpers. * fix(templating): (T1) close two plugin-registry trust-cache gaps (#10326) * fix(templating): close two plugin-registry trust-cache gaps - pluginConfig.elevated is keyed by declared plugin name, not by folder; a same-named folder placed alongside an already-elevated plugin inherited its trust grant and ran in-process before any collision was even noticed. traversePluginPath now pre-scans for duplicate names (order-independent) and refuses to load any colliding folder. - applyRequestHooks/applyResponseHooks tagged a caught error with `error.plugin = plugin`, a plain assignment that a plugin-thrown Error could intercept via its own `plugin` property setter, handing the hook a live, mutable reference to its own cached registry entry and letting it flip `directory`/`config.elevated` to defeat later sandboxing. Switched to Object.defineProperty, which bypasses any such setter. * fix(plugins): use relative-path containment check instead of startsWith A bare .startsWith(base) on a resolved path accepts a sibling directory whose name happens to prefix-match the base (e.g. /plugins-evil vs /plugins). Added a shared isContainedIn helper (path.relative, rejects .. or an absolute result) and applied it to both the existing plugin-path containment check and the new duplicate-name pre-pass. * fix(templating): (T1) address Copilot review — skip CLI settings read, scope bundle-tag sandbox to legacy flag - network-adapter.node.ts: only read services.settings.get() when canSandbox (Electron). The pure-Node inso CLI can never reach the sandbox host, so the read was wasted work; pass undefined otherwise (shouldSandboxPlugin treats it as off). Both applyRequestHooks and applyResponseHooks. - templating-worker-database.ts: bundle (first-party/trusted) template tags now sandbox only under the legacy templateTagSandboxEnabled experiment, not the new pluginSandboxEnabled. The T1 flag isolates *untrusted* plugins; sandboxing trusted bundle tags under it was an unintended behavior change. Dropped the now-unused isSandboxEnabled import. --------- Co-authored-by: kwburns-kong <kyle.burns@konghq.com>