From 7002e5156458c893d52e3cdeec0776bee70e2038 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Fri, 5 Oct 2018 21:21:40 +0200 Subject: [PATCH] feat: app.enableSandbox() --- atom/browser/api/atom_api_app.cc | 45 ++++++++++------ atom/browser/api/atom_api_app.h | 1 + docs/api/app.md | 6 +++ spec/api-app-spec.js | 57 ++++++++++++++++++++- spec/fixtures/api/mixed-sandbox-app/main.js | 6 ++- 5 files changed, 96 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index c81a4ed856585..e0e5af6b70385 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -1184,23 +1184,10 @@ v8::Local App::GetGPUInfo(v8::Isolate* isolate, return promise->GetHandle(); } -void App::EnableMixedSandbox(mate::Arguments* args) { - if (Browser::Get()->is_ready()) { - args->ThrowError( - "app.enableMixedSandbox() can only be called " - "before app is ready"); - return; - } - - auto* command_line = base::CommandLine::ForCurrentProcess(); +static void RemoveNoSandboxSwitch(base::CommandLine* command_line) { if (command_line->HasSwitch(service_manager::switches::kNoSandbox)) { -#if defined(OS_WIN) - const base::CommandLine::CharType* noSandboxArg = L"--no-sandbox"; -#else - const base::CommandLine::CharType* noSandboxArg = "--no-sandbox"; -#endif - - // Remove the --no-sandbox switch + const base::CommandLine::CharType* noSandboxArg = + FILE_PATH_LITERAL("--no-sandbox"); base::CommandLine::StringVector modified_command_line; for (auto& arg : command_line->argv()) { if (arg.compare(noSandboxArg) != 0) { @@ -1209,6 +1196,31 @@ void App::EnableMixedSandbox(mate::Arguments* args) { } command_line->InitFromArgv(modified_command_line); } +} + +void App::EnableSandbox(mate::Arguments* args) { + if (Browser::Get()->is_ready()) { + args->ThrowError( + "app.enableSandbox() can only be called " + "before app is ready"); + return; + } + + auto* command_line = base::CommandLine::ForCurrentProcess(); + RemoveNoSandboxSwitch(command_line); + command_line->AppendSwitch(switches::kEnableSandbox); +} + +void App::EnableMixedSandbox(mate::Arguments* args) { + if (Browser::Get()->is_ready()) { + args->ThrowError( + "app.enableMixedSandbox() can only be called " + "before app is ready"); + return; + } + + auto* command_line = base::CommandLine::ForCurrentProcess(); + RemoveNoSandboxSwitch(command_line); command_line->AppendSwitch(switches::kEnableMixedSandbox); } @@ -1316,6 +1328,7 @@ void App::BuildPrototype(v8::Isolate* isolate, .SetMethod("startAccessingSecurityScopedResource", &App::StartAccessingSecurityScopedResource) #endif + .SetMethod("enableSandbox", &App::EnableSandbox) .SetMethod("enableMixedSandbox", &App::EnableMixedSandbox); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 2e775a6c00448..166438f30f776 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -203,6 +203,7 @@ class App : public AtomBrowserClient::Delegate, v8::Local GetGPUFeatureStatus(v8::Isolate* isolate); v8::Local GetGPUInfo(v8::Isolate* isolate, const std::string& info_type); + void EnableSandbox(mate::Arguments* args); void EnableMixedSandbox(mate::Arguments* args); #if defined(OS_MACOSX) diff --git a/docs/api/app.md b/docs/api/app.md index e4ac418a7cf5b..9e57c83dfbe79 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1089,6 +1089,12 @@ correctly. **Note:** This will not affect `process.argv`. +### `app.enableSandbox()` _Experimental_ _macOS_ _Windows_ + +Enables full sandbox mode on the app. + +This method can only be called before app is ready. + ### `app.enableMixedSandbox()` _Experimental_ _macOS_ _Windows_ Enables mixed sandbox mode on the app. diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 0e592ac84fe5c..847c38bdfcfd7 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -871,7 +871,7 @@ describe('app module', () => { }) }) - describe('mixed sandbox option', () => { + describe('sandbox options', () => { let appProcess = null let server = null const socketPath = process.platform === 'win32' ? '\\\\.\\pipe\\electron-mixed-sandbox' : '/tmp/electron-mixed-sandbox' @@ -903,10 +903,60 @@ describe('app module', () => { }) }) + describe('when app.enableSandbox() is called', () => { + it('adds --enable-sandbox to all render processes', done => { + const appPath = path.join(__dirname, 'fixtures', 'api', 'mixed-sandbox-app') + appProcess = ChildProcess.spawn(remote.process.execPath, [appPath, '--app-enable-sandbox']) + + server.once('error', error => { done(error) }) + + server.on('connection', client => { + client.once('data', data => { + const argv = JSON.parse(data) + expect(argv.sandbox).to.include('--enable-sandbox') + expect(argv.sandbox).to.not.include('--no-sandbox') + + expect(argv.noSandbox).to.include('--enable-sandbox') + expect(argv.noSandbox).to.not.include('--no-sandbox') + + expect(argv.noSandboxDevtools).to.be.true() + expect(argv.sandboxDevtools).to.be.true() + + done() + }) + }) + }) + }) + + describe('when the app is launched with --enable-sandbox', () => { + it('adds --enable-sandbox to all render processes', done => { + const appPath = path.join(__dirname, 'fixtures', 'api', 'mixed-sandbox-app') + appProcess = ChildProcess.spawn(remote.process.execPath, [appPath, '--enable-sandbox']) + + server.once('error', error => { done(error) }) + + server.on('connection', client => { + client.once('data', data => { + const argv = JSON.parse(data) + expect(argv.sandbox).to.include('--enable-sandbox') + expect(argv.sandbox).to.not.include('--no-sandbox') + + expect(argv.noSandbox).to.include('--enable-sandbox') + expect(argv.noSandbox).to.not.include('--no-sandbox') + + expect(argv.noSandboxDevtools).to.be.true() + expect(argv.sandboxDevtools).to.be.true() + + done() + }) + }) + }) + }) + describe('when app.enableMixedSandbox() is called', () => { it('adds --enable-sandbox to render processes created with sandbox: true', done => { const appPath = path.join(__dirname, 'fixtures', 'api', 'mixed-sandbox-app') - appProcess = ChildProcess.spawn(remote.process.execPath, [appPath]) + appProcess = ChildProcess.spawn(remote.process.execPath, [appPath, '--app-enable-mixed-sandbox']) server.once('error', error => { done(error) }) @@ -919,6 +969,9 @@ describe('app module', () => { expect(argv.noSandbox).to.not.include('--enable-sandbox') expect(argv.noSandbox).to.include('--no-sandbox') + expect(argv.noSandboxDevtools).to.be.true() + expect(argv.sandboxDevtools).to.be.true() + done() }) }) diff --git a/spec/fixtures/api/mixed-sandbox-app/main.js b/spec/fixtures/api/mixed-sandbox-app/main.js index c63201a8de576..1c2ea79fc6049 100644 --- a/spec/fixtures/api/mixed-sandbox-app/main.js +++ b/spec/fixtures/api/mixed-sandbox-app/main.js @@ -6,7 +6,11 @@ process.on('uncaughtException', () => { app.exit(1) }) -if (!process.argv.includes('--enable-mixed-sandbox')) { +if (process.argv.includes('--app-enable-sandbox')) { + app.enableSandbox() +} + +if (process.argv.includes('--app-enable-mixed-sandbox')) { app.enableMixedSandbox() }