electron: The SUID sandbox helper binary was found, but is not configured correctly

Preflight Checklist

  • I have read the Contributing Guidelines for this project.
  • I agree to follow the Code of Conduct that this project adheres to.
  • I have searched the issue tracker for an issue that matches the one I want to file, without success.

Issue Details

  • Electron Version:
    • 5.0.0
  • Operating System:
    • Arch Linux x64
  • Last Known Working Electron version::
    • 4.1.5

Expected Behavior

Running node_modules/.bin/electron --version should output v5.0.0.

To be clear, all commands create this error, but I’m using the --version flag for simplicity.

Actual Behavior

$ node_modules/.bin/electron --version
[2720:0425/142001.775056:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /home/christianbundy/src/ssbc/patchwork/node_modules/electron/dist/chrome-sandbox is owned by root and has mode 4755.

Additional Information

$ stat /home/christianbundy/src/ssbc/patchwork/node_modules/electron/dist/chrome-sandbox
  Size: 5185424   	Blocks: 10128      IO Block: 4096   regular file
Device: 802h/2050d	Inode: 1465270     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/christianbundy)   Gid: ( 1000/christianbundy)
Access: 2019-04-25 14:15:10.609279524 -0700
Modify: 2019-04-25 14:15:10.659278929 -0700
Change: 2019-04-25 14:15:10.659278929 -0700
 Birth: 2019-04-25 14:15:10.609279524 -0700

If I chown and chmod the file then it works fine, but my intuition is that npm install electron@latest should work without those commands. Is this expected behavior?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 42
  • Comments: 155 (24 by maintainers)

Commits related to this issue

Most upvoted comments

CONFIG_USER_NS=y enables the user namespaces feature, but they’re still restricted to privileged users by default. This suggests sysctl kernel.unprivileged_userns_clone=1

CONFIG_USER_NS=y enables the user namespaces feature, but they’re still restricted to privileged users by default. This suggests sysctl kernel.unprivileged_userns_clone=1

I confirm executing sudo sysctl kernel.unprivileged_userns_clone=1 is another workaround, related comment.

Is there a possible workaround in the meantime until every linux distro enables those features?

See the original message:

If I chown and chmod the file then it works fine

Also see here https://github.com/electron/electron/issues/16631#issuecomment-476082063 So to make suid sandbox work you basically have to tweak the chrome-sandbox binary this way:

  • sudo chown root chrome-sandbox
  • chmod 4755 chrome-sandbox

The issue is more severe though if running appimage/snap packages, I have not yet revealed a decent workaround for these cases. It’s working if appimage is executed with --no-sandbox arguemnt, but this is a hack.

This solution only work when you get this error because of WSL

I ran into this issue while trying to use electron on WSL (WSL2 on my case). Even by using an X11 server, electron was not able to run over X11.

I had to build electron for Windows, even if I run it inside WSL. After that, everything work as excepted The simplest way to do that:

  • Uninstall electron npm uninstall electron
  • Change npm config platform export npm_config_platform=win32
  • Install electron npm install electron
  • Unset the environment variable unset npm_config_platform

@nornagon

because setting the appropriate permissions requires root privileges and we don’t want to ask for a root password during npm install.

Executing chmod 4755 node_modules/electron/dist/chrome-sandbox doesn’t require root permission and that should be enough to run such command for wrapping the app to deb/pacman/etc packages as when such packages get installed all the files including chrome-sandbox normally owned by root. So it would be great electron does chmod 4755 node_modules/electron/dist/chrome-sandbox automatically during installation process as then there would be no need to handle this case manually like mentioned here.

For me sudo chown root chrome-sandbox & chmod 4755 chrome-sandbox didn’t work.

The issue was that I did npm install electron --save-dev on my WSL(Windows Subsystem for Linux).

To install electron on Windows and run from WSL:

  • Uninstall electron npm uninstall electron
  • Change npm config platform export npm_config_platform=win32
  • Install electron npm install electron
  • Unset the environment variable unset npm_config_platform

Source: https://github.com/mayeaux/videodownloader/issues/4#issuecomment-578429939

@vladimiry I needed to first chown and then chmod. The other way round it didn’t work.

Here’s the situation:

  • Electron v5 enabled mixed-mode sandboxing (i.e. some processes being sandboxed and others not) on Linux. This doesn’t change whether your renderer processes are sandboxed by default, but it does mean that the GPU process is now sandboxed.
  • Chromium’s sandbox on Linux uses an OS feature called CLONE_NEWUSER. Some kernels are built with this feature restricted to privileged users out of an abundance of caution. You can read more about it here [lwn, 2016].
  • When CLONE_NEWUSER is unavailable, Chromium falls back to using a different sandboxing mechanism that requires a helper binary that is setuid to root. If this binary is not present or doesn’t have the right permissions (4755 and owned by root), the sandbox will fail to boot.
  • Setting the helper binary permissions must be done by a privileged user (i.e. root). We do not set these permissions on npm install, because we don’t want to ask for root access during npm install.
  • The Electron v5 release packages include the helper binary, but it is up to the various packaging and distribution tools to ensure that it gets the right permissions and ownership.

There are two workarounds:

  1. Enable unprivileged access to CLONE_NEWUSER in your kernel. Some kernels support changing this with sysctl kernel.unprivileged_userns_clone=1.
  2. Disable sandboxing entirely by launching with --no-sandbox. Adding this argument from JS is unfortunately insufficient, as the GPU process is launched before the main process JS is run.

We will not support automatically disabling the sandbox in Electron when these conditions are detected. You must ensure that your distributed packages to set the appropriate permissions. Most tools (at least electron-builder, electron-installer-snap, electron-installer-debian, and electron-installer-redhat) support this automatically and require no configuration from the developer. If you’re using a different tool that does not support this, please raise an issue on that tool and link to this comment.

I’m closing this issue because, as mentioned in the previous paragraph, we will not be changing the requirement that Electron in production requires access to a functioning sandbox unless explicitly instructed otherwise. However, to ease development, I have opened #19550 to track the option of automatically degrading to non-sandboxed mode when Electron is installed via npm install, rather than via a distributed package.

Please stop recommending sudo as the solution. Not every user on a system has sudo permissions. I do not get why a non system app needs sudo permissions. This issue makes pretty much all Electron apps being crippled on Debian and Arch which are the most installed and used Linux distributions.

Also --no-sandbox does not work

 ./tabby --no-sandbox

innerError Error: Cannot find module '../build/Debug/pty.node'
Require stack:
- /home/USER/apps/tabby/resources/app.asar/node_modules/@tabby-gang/node-pty/lib/unixTerminal.js
- /home/USER/apps/tabby/resources/app.asar/node_modules/@tabby-gang/node-pty/lib/index.js
- /home/USER/apps/tabby/resources/app.asar/dist/main.js
-
    at Module._resolveFilename (internal/modules/cjs/loader.js:887:15)
    at Function.n._resolveFilename (electron/js2c/browser_init.js:257:1128)
    at Module._load (internal/modules/cjs/loader.js:732:27)
    at Function.f._load (electron/js2c/asar_bundle.js:5:12913)
    at Module.require (internal/modules/cjs/loader.js:959:19)
    at require (/home/USER/apps/tabby/resources/app.asar/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at Object.<anonymous> (/home/USER/apps/tabby/resources/app.asar/node_modules/@tabby-gang/node-pty/lib/unixTerminal.js:33:15)
    at Module._compile (/home/USER/apps/tabby/resources/app.asar/node_modules/v8-compile-cache/v8-compile-cache.js:192:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1108:10)
    at Module.load (internal/modules/cjs/loader.js:935:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/USER/apps/tabby/resources/app.asar/node_modules/@tabby-gang/node-pty/lib/unixTerminal.js',
    '/home/USER/apps/tabby/resources/app.asar/node_modules/@tabby-gang/node-pty/lib/index.js',
    '/home/USER/apps/tabby/resources/app.asar/dist/main.js',
    undefined
  ]
}



Is there any way where the end user doesn’t have to do any extra work?

Yes, there is a way, it has been discussed before.

@nornagon so we can’t even run Electron 6 on Debian and there is no way we’re giving a chrome process root perms. The workarounds given are not sufficient from the user perspective.

There are two workarounds: Enable unprivileged access to CLONE_NEWUSER in your kernel. Some kernels support changing this with sysctl kernel.unprivileged_userns_clone=1.

There is absolutely no way messing with the customers computer is the way to go about this.

Disable sandboxing entirely by launching with --no-sandbox. Adding this argument from JS is unfortunately insufficient, as the GPU process is launched before the main process JS is run.

How about adding a --sandbox flag and turn off the sandbox feature by default? This has a benefit of not screwing 99% of folks using Electron.

This suggests sysctl kernel.unprivileged_userns_clone=1

I see this issue with WSL (Windows 10), Ubuntu 18.04 installed into WSL. sudo sysctl kernel.unprivileged_userns_clone=1 does not work.

sudo sysctl kernel.unprivileged_userns_clone=1
sysctl: cannot stat /proc/sys/kernel/unprivileged_userns_clone: No such file or directory

Using chown and chmod is also not an option.

For a better developer experience. We can set up a command as bellow within electron cli tool.

sudo chown root pathToChromeSandboxDynamicallyGenearted && sudo chmod 4755 pathToChromeSandboxDynamicallyGenearted

A command like electron --ConfigSandbox. The user will be aware and the sandbox can be easily configured. And even when it’s first run. We can ask them if they want to take the actions. y or n. And then all they need to do is enter the password. That way it will be done in a glance. And it will lead to a big user experience and win in time. Cause you’ll trust the vendor or the community. And go with it. In place of searching all over the net. And that’s even more valuable for the more beginners of us. And it’s nice in all cases.

@black-puppydog As I recall, the installer prompts you for a root password when you first install Debian on your machine. But yes, on Debian (or any other system that uses Debian’s kernel patch), you need to either have root access (via sudo or otherwise), or run Electron apps with --no-sandbox.

@ndorf In mainline Linux, user namespaces can be disabled by not compiling in the feature, but they cannot be enabled/disabled at run time or restricted to privileged processes only. Debian patches its kernels such that user namespaces are restricted to privileged processes by default, but can be enabled for all processes with a setting under /proc/sys.

The reason Debian restricts it is that unprivileged user namespaces are a serious security risk with a long history of vulnerabilities. Unprivileged user namespaces allow unprivileged processes access to a lot of kernel functionality (UID 0, capabilities, mount a file system, create a device inode, etc) that was restricted to privileged processes only for a very long time. Any kernel code relying on the assumption that unprivileged processes will never be able to do these things is vulnerable now that unprivileged processes suddenly are able to do these things.

@cuixiping it works 👍

I did

$ find . -name chrome-sandbox
./node_modules/electron/dist/chrome-sandbox

$ sudo chown root ./node_modules/electron/dist/chrome-sandbox

$ sudo chmod 4755 ./node_modules/electron/dist/chrome-sandbox

@p3x-robot I still tend to think that you have to admit that there is nothing to fix.

As for now, I like more the first option.

  1. Boot without sandbox if no sandboxing method is available only when booting an unpackaged app. If Electron is booting a packaged app, refuse to boot without sandbox.

Such scenario would be somehow misleading. One might be successfully running unpackaged app without sandboxing, but there is a chance that the packaged app won’t work the same way with enabled sandboxing. Like, for example, the case when you access the main process from the renderer process not through the remote interface. Or the case of wrapping the app to AppImage / Snap / Flatpak packages.

  1. In all cases, if no sandboxing method is available, boot without sandboxing and print a warning.

So a packaged app that was designed and developed as sandboxed might be executed without sandbox if no sandbox available. This doesn’t sound good to me.

  1. Disable sandboxing by default on Linux.

What does it mean exactly? What would be the way to enable sandboxing on Linux in the way the app either starts or fails if no sandboxing available (the current situation, forced sandboxing).

@MarshallOfSound zip does not support permissions, but ultimately the issue is not the chmod permission, but rather the owner. The setuid sandbox helper is suid to root, because it needs to perform functions that are only available to root. If it were possible to set the appropriate permissions without first gaining root privileges, that would be a very serious vulnerability in Linux. Fortunately for Linux, and unfortunately for us, that is not the case.

Here are the options as I see them:

  1. Change nothing in Electron. Recommend that developers enable unprivileged CLONE_USERNS on their kernel to allow the namespace sandbox to run instead of the setuid sandbox.
  2. Boot without sandbox if no sandboxing method is available only when booting an unpackaged app. If Electron is booting a packaged app, refuse to boot without sandbox.
  3. In all cases, if no sandboxing method is available, boot without sandboxing and print a warning.
  4. Disable sandboxing by default on Linux.

I’m leaning towards (2). It would ease development without compromising the security of the deployed app.

I’m not yet sure what to do about snap/flatpak, as I’m not familiar with their workings. It’s possible that they already sandbox the app sufficiently that we can disable sandboxing altogether in that situation, as we do when building the Mac App Store version of Electron.

sudo chown root chrome-sandbox
sudo chmod 4755 chrome-sandbox

This works well.

Pardon my boldness, but this is absolutely insane. Electron exposes the Node.js API even in renderer processes. Using/enabling Chromium’s sandbox in an Electron app is completely pointless, and as you all can see from the bug reports around GitHub pointing to this issue, it’s also highly counterproductive. Please disable it if possible.

Could Electron try some code like that if the sandbox error occurs, before killing the process? Or is this something I could invoke with a bash file?

Yeah, passing --no-sandbox argument to the electron app binary in general is supposed to work around the issue.

Depending on the installation package you could set the SUID permission bit (4755) to chrome-sandbox binary (for packages like deb, pacman, etc) or hardcode the --no-sandbox argument to the loader sh/bash script (for packages like Snap and AppImage). This is what I currently do and so there is no need to do anything for the app users (no sudo access required).

The recent electron-builder release already comes with hardcoding the --no-sandbox argument but only for the Snap package.

@burningTyger you are right, I just have changed the original message.

@kitingChris The setuid sandbox IS the workaround. You just need to ensure that when developing / releasing an electron app your dev / packaging scripts set the permissions of the sandbox helper correctly as @nornagon linked above.

Additionally, I understand that I have both the options either setting 4755 bit or setting no-sandbox.

If I remember things correctly, settings 4755 to appimage won’t solve the issue. You need to (one of):

  • start your appimage file with --no-sandbox command line arg
  • have --no-sandbox embedded into the ./AppRun script located in your appimage file (so repackaging needed).

Can you point me to the right documentation which can help me in how to do that.

I doubt you will find detailed information about the issue in any documentation. I’m not aware of any relevant docs.

path for users with no root access to use electron easily

--no-sandbox CLI argument.

@shrinidhi111 4755 can be preserved when packaged, at least in the case of pacman/deb packages. The packages can also be tweaked on the specific-dist level, eg. As for the root owner, normally when the package installed from the repo on Linux the related files get root owner. In the case of AppImage build I repackage it and hardcode --no-sandbox arg in the inner AppRun script as electron-builder doesn’t do that yet out from the box. Snap package is formed by electron-builder with hardcoded --no-sandbox arg (related fix added ~6 months ago).

CONFIG_USER_NS=y enables the user namespaces feature, but they’re still restricted to privileged users by default. This suggests sysctl kernel.unprivileged_userns_clone=1

I confirm executing sudo sysctl kernel.unprivileged_userns_clone=1 is another workaround, related comment.

Yeap I use manjaro and i3wm, I took the same error but with this it’s working.

@pronebird chrome-sandbox binary definitely shouldn’t be 5MB, that’s a bug. Opened #20049 to fix it, thanks for pointing it out.

You’re certainly welcome to choose to disable sandboxing for your use case. It’s unfortunate that Chromium’s architecture makes it so that you have to pass --no-sandbox on the command line directly rather than calling app.commandLine.appendSwitch; ideally disabling the sandbox would be possible without necessitating a wrapper script. Hopefully with #20049 the concern of removing the binary will be ameliorated, since 200KB extra is much more reasonable to live with than 5MB.

The workarounds given are not sufficient from the user perspective.

Using loader-like script/program which will add --no-sandbox arg can also be considered as a workaround, so no end-user actions needed. Besides such loader could test user namespace support first and add --no-sandbox only if required.

If anyone is looking for a solution to this check out @thomasnordquist’s solution or my adaptation of it, they work by disabling the sandbox under Linux.

@JCMais it sounds like Electron is incorrectly attempting to use the namespace sandbox within docker, even though it should be trying to use the suid sandbox. I’m not sure why that would be, but you can force the suid sandbox with --disable-namespace-sandbox. If you launch docker with --privileged (or --cap-add SYS_ADMIN, or a custom seccomp profile that allows CLONE_NEWUSER), then namespaces will be available inside the sandbox and there’s no need for the setuid sandbox or its helper executable.

Just to be clear, for Snaps there was more to it (namely, adding browser sandbox support as noted above). See the associated PR’s changes for details.

I agree that doing anything that would require root privileges during npm install is a non-starter. Which is why I did not list it as one of the options.

Doing a sudo chown root:root && sudo chmod 475 on npm install should be out of the question

This is not considered as an option as far as I understand.

chown root:root chrome-sandbox && chmod 4755 chrome-sandbox raises some red flags for me.

Of course, it does. But you can enable User Namespace sandboxing as an alternative sudo sysctl kernel.unprivileged_userns_clone=1 (enabled by default on Ubuntu but not on Arch).

chown root:root chrome-sandbox && chmod 4755 chrome-sandbox raises some red flags for me.

Just to be very clear on what it does: It sets the SUID bit on chrome-sandbox, which makes any user able to execute the file as root. This means that if there is any way to use chrome-sandbox maliciously, or if the contents ever gets malicious, any user could become root. chrome-sandbox would be a very interesting target for attack.

I strongly recommend against doing this workaround on npm install, because it would require sudo (user needs to write password), it’s invasive and we might not understand the security consequences of doing so.

I also like (1), but to defend (2) a little, the API exposed to the app wouldn’t change when disabling the sandbox. The only thing we would disable is the OS-level sandbox. We would still load the app the same way, it just wouldn’t be protected by the OS.