PageSourceSearch

https://www.electronjs.org/assets/js/dc4b1e08.38258e80.js

js electronjs.org collected 2026-09-24 07:03:15 UTC 16,050 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkelectronjs=self.webpackChunkelectronjs||[]).push([["18669"],{44585(e,n,s){s.r(n),s.d(n,{metadata:()=>o,default:()=>h,frontMatter:()=>i,contentTitle:()=>a,toc:()=>l,assets:()=>d});var o=JSON.parse('{"id":"latest/tutorial/sandbox","title":"Process Sandboxing","description":"One key security feature in Chromium is that processes can be executed within a sandbox. The sandbox limits the harm that malicious code can cause by limiting access to most system resources \u2014 sandboxed processes can only freely use CPU cycles and memory. In order to perform operations requiring additional privilege, sandboxed processes use dedicated communication channels to delegate tasks to more privileged processes.","source":"@site/docs/latest/tutorial/sandbox.md","sourceDirName":"latest/tutorial","slug":"/latest/tutorial/sandbox","permalink":"/docs/latest/tutorial/sandbox","draft":false,"unlisted":false,"editUrl":"https://github.com/electron/electron/edit/main/docs/tutorial/sandbox.md","tags":[],"version":"current","frontMatter":{"title":"Process Sandboxing","description":"One key security feature in Chromium is that processes can be executed within a sandbox. The sandbox limits the harm that malicious code can cause by limiting access to most system resources \u2014 sandboxed processes can only freely use CPU cycles and memory. In order to perform operations requiring additional privilege, sandboxed processes use dedicated communication channels to delegate tasks to more privileged processes.","slug":"sandbox","hide_title":false},"sidebar":"docs","previous":{"title":"Inter-Process Communication","permalink":"/docs/latest/tutorial/ipc"},"next":{"title":"MessagePorts in Electron","permalink":"/docs/latest/tutorial/message-ports"}}'),r=s(74848),t=s(28453);let i={title:"Process Sandboxing",description:"One key security feature in Chromium is that processes can be executed within a sandbox. The sandbox limits the harm that malicious code can cause by limiting access to most system resources \u2014 sandboxed processes can only freely use CPU cycles and memory. In order to perform operations requiring additional privilege, sandboxed processes use dedicated communication channels to delegate tasks to more privileged processes.",slug:"sandbox",hide_title:!1},a="Process Sandboxing",d={},l=[{value:"Sandbox behavior in Electron",id:"sandbox-behavior-in-electron",level:2},{value:"Renderer processes",id:"renderer-processes",level:3},{value:"Preload scripts",id:"preload-scripts",level:3},{value:"Configuring the sandbox",id:"configuring-the-sandbox",level:2},{value:"Disabling the sandbox for a single process",id:"disabling-the-sandbox-for-a-single-process",level:3},{value:"Enabling the sandbox globally",id:"enabling-the-sandbox-globally",level:3},{value:"Disabling Chromium's sandbox (testing only)",id:"disabling-chromiums-sandbox-testing-only",level:3},{value:"A note on rendering untrusted content",id:"a-note-on-rendering-untrusted-content",level:2}];function c(e){let n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"process-sandboxing",children:"Process Sandboxing"})}),"\n",(0,r.jsx)(n.p,{children:"One key security feature in Chromium is that processes can be executed within a sandbox.\nThe sandbox limits the harm that malicious code can cause by limiting access to most\nsystem resources \u2014 sandboxed processes can only freely use CPU cycles and memory.\nIn order to perform operations requiring additional privilege, sandboxed processes\nuse dedicated communication channels to delegate tasks to more privileged processes."}),"\n",(0,r.jsx)(n.p,{children:"In Chromium, sandboxing is applied to most processes other than the main process.\nThis includes renderer processes, as well as utility processes such as the audio service,\nthe GPU service and the network service."}),"\n",(0,r.jsxs)(n.p,{children:["See Chromium's ",(0,r.jsx)(n.a,{href:"https://chromium.googlesource.com/chromium/src/+/main/docs/design/sandbox.md",children:"Sandbox design document"})," for more information."]}),"\n",(0,r.jsx)(n.p,{children:"Starting from Electron 20, the sandbox is enabled for renderer processes without any\nfurther 
1configuration."}),"\n",(0,r.jsxs)(n.p,{children:["Sandboxing is tied to Node.js integration. ",(0,r.jsx)(n.em,{children:"Enabling Node.js integration"})," for a\nrenderer process by setting ",(0,r.jsx)(n.code,{children:"nodeIntegration: true"})," ",(0,r.jsx)(n.em,{children:"disables the sandbox"})," for the\nprocess."]}),"\n",(0,r.jsxs)(n.p,{children:["If you want to disable the sandbox for a process, see the\n",(0,r.jsx)(n.a,{href:"#disabling-the-sandbox-for-a-single-process",children:"Disabling the sandbox for a single process"}),"\nsection."]}),"\n",(0,r.jsx)(n.h2,{id:"sandbox-behavior-in-electron",children:"Sandbox behavior in Electron"}),"\n",(0,r.jsxs)(n.p,{children:["Sandboxed processes in Electron behave ",(0,r.jsx)(n.em,{children:"mostly"})," in the same way as Chromium's do, but\nElectron has a few additional concepts to consider because it interfaces with Node.js."]}),"\n",(0,r.jsx)(n.h3,{id:"renderer-processes",children:"Renderer processes"}),"\n",(0,r.jsx)(n.p,{children:"When renderer processes in Electron are sandboxed, they behave in the same way as a\nregular Chromium renderer would. A sandboxed renderer won't have a Node.js\nenvironment initialized."}),"\n",(0,r.jsx)(n.p,{children:"Therefore, when the sandbox is enabled, renderer processes can only perform privileged\ntasks (such as interacting with the filesystem, making changes to the system, or spawning\nsubprocesses) by delegating these tasks to the main process via inter-process\ncommunication (IPC)."}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["For more info on inter-process communication, check out our ",(0,r.jsx)(n.a,{href:"/docs/latest/tutorial/ipc",children:"IPC guide"}),"."]})}),"\n",(0,r.jsx)(n.h3,{id:"preload-scripts",children:"Preload scripts"}),"\n",(0,r.jsxs)(n.p,{children:["In order to allow renderer processes to communicate with the main process, preload\nscripts attached to sandboxed renderers will still have a polyfilled subset of Node.js\nAPIs available. A ",(0,r.jsx)(n.code,{children:"require"})," function similar to Node's ",(0,r.jsx)(n.code,{children:"require"})," module is exposed,\nbut can only import a subset of Electron and Node's built-in modules:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"electron"})," (following renderer process modules: ",(0,r.jsx)(n.code,{children:"contextBridge"}),", ",(0,r.jsx)(n.code,{children:"crashReporter"}),", ",(0,r.jsx)(n.code,{children:"ipcRenderer"}),", ",(0,r.jsx)(n.code,{children:"nativeImage"}),", ",(0,r.jsx)(n.code,{children:"webFrame"}),", ",(0,r.jsx)(n.code,{children:"webUtils"}),")"]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/events.html",children:(0,r.jsx)(n.code,{children:"events"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/timers.html",children:(0,r.jsx)(n.code,{children:"timers"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/url.html",children:(0,r.jsx)(n.code,{children:"url"})})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://nodejs.org/api/esm.html#node-imports",children:"node: imports"})," are supported as well:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/events.html",children:(0,r.jsx)(n.code,{children:"node:events"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/timers.html",children:(0,r.jsx)(n.code,{children:"node:timers"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/url.html",children:(0,r.jsx)(n.code,{children:"node:url"})})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"In addition, the preload script also polyfills certain Node.js primitives as globals:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/buffer.html",children:(0,r.jsx)(n.code,{children:"Buffer"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/docs/latest/api/process",children:(0,r.jsx)(n.code,{children:"process"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/timers.html#timers_clearimmediate_immediate",children:(0,r.jsx)(n.code,{children:"clearImmediate"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/timers.html#timers_setimmediate_callback_args",children:(0,r.jsx)(n.code,{children:"setImmediate"})})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Because the ",(0,r.jsx)(n.code,{children:"require"})," function is a polyfill with limited functionality, you will not be\nable to use ",(0,r.jsx)(n.a,{href:"https://nodejs.org/api/modules.html#modules_modules_commonjs_modules",children:"CommonJS modules"})," to separate your preload script into multiple\nfiles. If you need to split your preload code, use a bundler such as ",(0,r.jsx)(n.a,{href:"https://webpack.js.org/",children:"webpack"}),"\nor ",(0,r.jsx)(n.a,{href:"https://parceljs.org/",children:"Parcel"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Note that because the environment presented to the ",(0,r.jsx)(n.code,{children:"preload"})," script is substantially\nmore privileged than that of a sandboxed renderer, it is still possible to leak\nprivileged APIs to untrusted code running in the renderer process unless\n",(0,r.jsx)(n.a,{href:"/docs/latest/tutorial/context-isolation",children:(0,r.jsx)(n.code,{children:"contextIsolation"})})," is enabled."]}),"\n",(0,r.jsx)(n.h2,{id:"configuring-the-sandbox",children:"Configuring the sandbox"}),"\n",(0,r.jsx)(n.p,{children:"For most apps, sandboxing is the best choice. In certain use cases that are incompatible with\nthe sandbox (for instance, when using native node modules in the renderer),\nit is possible to disable the sandbox for specific processes. This comes with security\nrisks, especially if any untrusted code or content is present in the unsandboxed process."}),"\n",(0,r.jsx)(n.h3,{id:"disabling-the-sandbox-for-a-single-process",children:"Disabling the sandbox for a single process"}),"\n",(0,r.jsxs)(n.p,{children:["In Electron, renderer sandboxing can be disabled on a per-process basis with\nthe ",(0,r.jsx)(n.code,{children:"sandbox: false"})," preference in the ",(0,r.jsx)(n.a,{href:"/docs/latest/api/browser-window",children:(0,r.jsx)(n.code,{children:"BrowserWindow"})})," constructor."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",metastring:"title='main.js'",children:"app.whenReady().then(() =>
1 {\n  const win = new BrowserWindow({\n    webPreferences: {\n      sandbox: false\n    }\n  })\n  win.loadURL('https://google.com')\n})\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Sandboxing is also disabled whenever Node.js integration is enabled in the renderer.\nThis can be done through the BrowserWindow constructor with the ",(0,r.jsx)(n.code,{children:"nodeIntegration: true"})," flag\nor by providing the respective HTML boolean attribute for a ",(0,r.jsx)(n.code,{children:"webview"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",metastring:"title='main.js'",children:"app.whenReady().then(() => {\n  const win = new BrowserWindow({\n    webPreferences: {\n      nodeIntegration: true\n    }\n  })\n  win.loadURL('https://google.com')\n})\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-html",metastring:"title='index.html (Renderer Process)'",children:'<webview nodeIntegration src="page.html"></webview>\n'})}),"\n",(0,r.jsx)(n.h3,{id:"enabling-the-sandbox-globally",children:"Enabling the sandbox globally"}),"\n",(0,r.jsxs)(n.p,{children:["If you want to force sandboxing for all renderers, you can also use the\n",(0,r.jsx)(n.a,{href:"/docs/latest/api/app#appenablesandbox",children:(0,r.jsx)(n.code,{children:"app.enableSandbox"})})," API. Note that this API has to be called before the\napp's ",(0,r.jsx)(n.code,{children:"ready"})," event."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",metastring:"title='main.js'",children:"app.enableSandbox()\napp.whenReady().then(() => {\n  // any sandbox:false calls are overridden since `app.enableSandbox()` was called.\n  const win = new BrowserWindow()\n  win.loadURL('https://google.com')\n})\n"})}),"\n",(0,r.jsx)(n.h3,{id:"disabling-chromiums-sandbox-testing-only",children:"Disabling Chromium's sandbox (testing only)"}),"\n",(0,r.jsxs)(n.p,{children:["You can also disable Chromium's sandbox entirely with the ",(0,r.jsx)(n.a,{href:"/docs/latest/api/command-line-switches#--no-sandbox",children:(0,r.jsx)(n.code,{children:"--no-sandbox"})}),"\nCLI flag, which will disable the sandbox for all processes (including utility processes).\nWe highly recommend that you only use this flag for testing purposes, and ",(0,r.jsx)(n.strong,{children:"never"}),"\nin production."]}),"\n",(0,r.jsxs)(n.p,{children:["Note that the ",(0,r.jsx)(n.code,{children:"sandbox: true"})," option will still disable the renderer's Node.js\nenvironment."]}),"\n",(0,r.jsx)(n.h2,{id:"a-note-on-rendering-untrusted-content",children:"A note on rendering untrusted content"}),"\n",(0,r.jsxs)(n.p,{children:["Rendering untrusted content in Electron is still somewhat uncharted territory,\nthough some apps are finding success (e.g. ",(0,r.jsx)(n.a,{href:"https://github.com/beakerbrowser/beaker",children:"Beaker Browser"}),").\nOur goal is to get as close to Chrome as we can in terms of the security of\nsandboxed content, but ultimately we will always be behind due to a few fundamental\nissues:"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"We do not have the dedicated resources or expertise that Chromium has to\napply to the security of its product. We do our best to make use of what we\nhave, to inherit everything we can from Chromium, and to respond quickly to\nsecurity issues, but Electron cannot be as secure as Chromium without the\nresources that Chromium is able to dedicate."}),"\n",(0,r.jsx)(n.li,{children:"Some security features in Chrome (such as Safe Browsing and Certificate\nTransparency) require a centralized authority and dedicated servers, both of\nwhich run counter to the goals of the Electron project. As such, we disable\nthose features in Electron, at the cost of the associated security they\nwould otherwise bring."}),"\n",(0,r.jsx)(n.li,{children:"There is only one Chromium, whereas there are many thousands of apps built\non Electron, all of which behave slightly differently. Accounting for those\ndifferences can yield a huge possibility space, and make it challenging to\nensure the security of the platform in unusual use cases."}),"\n",(0,r.jsx)(n.li,{children:"We can't push security updates to users directly, so we rely on app vendors\nto upgrade the version of Electron underlying their app in order for\nsecurity updates to reach users."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"While we make our best effort to backport Chromium security fixes to older\nversions of Electron, we do not make a guarantee that every fix will be\nbackported. Your best chance at staying secure is to be on the latest stable\nversion of Electron."})]})}function h(e={}){let{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453(e,n,s){s.d(n,{R:()=>i,x:()=>a});var o=s(96540);let r={},t=o.createContext(r);function i(e){let n=o.useContext(t);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.