Skip to content

Commit

Permalink
Add webPreferences.disableRemote option to disable the remote module …
Browse files Browse the repository at this point in the history
…(sandbox security)
  • Loading branch information
miniak committed May 21, 2018
1 parent ee57c95 commit 3dcd059
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 4 deletions.
14 changes: 12 additions & 2 deletions atom/browser/api/atom_api_web_contents.cc
Expand Up @@ -342,7 +342,8 @@ WebContents::WebContents(v8::Isolate* isolate,
type_(type),
request_id_(0),
background_throttling_(true),
enable_devtools_(true) {
enable_devtools_(true),
disable_remote_(false) {
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
if (type == REMOTE) {
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
Expand All @@ -362,7 +363,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
type_(BROWSER_WINDOW),
request_id_(0),
background_throttling_(true),
enable_devtools_(true) {
enable_devtools_(true),
disable_remote_(false) {
// Read options.
options.Get("backgroundThrottling", &background_throttling_);

Expand All @@ -389,6 +391,9 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
// Whether to enable DevTools.
options.Get("devTools", &enable_devtools_);

// Whether to disable remote.
options.Get("disableRemote", &disable_remote_);

// Obtain the session.
std::string partition;
mate::Handle<api::Session> session;
Expand Down Expand Up @@ -1922,6 +1927,10 @@ v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
return mate::ConvertToV8(isolate, *web_preferences->last_dict());
}

bool WebContents::IsRemoteDisabled() const {
return disable_remote_;
}

v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
if (owner_window())
return BrowserWindow::From(isolate(), owner_window());
Expand Down Expand Up @@ -2070,6 +2079,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getType", &WebContents::GetType)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
.SetMethod("_isRemoteDisabled", &WebContents::IsRemoteDisabled)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",
Expand Down
5 changes: 5 additions & 0 deletions atom/browser/api/atom_api_web_contents.h
Expand Up @@ -234,6 +234,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);

bool IsRemoteDisabled() const;

// Returns the owner window.
v8::Local<v8::Value> GetOwnerBrowserWindow();

Expand Down Expand Up @@ -454,6 +456,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Whether to enable devtools.
bool enable_devtools_;

// Whether to disable remote.
bool disable_remote_;

// Observers of this WebContents.
base::ObserverList<ExtendedWebContentsObserver> observers_;

Expand Down
1 change: 1 addition & 0 deletions docs/api/browser-window.md
Expand Up @@ -270,6 +270,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
are more limited. Read more about the option [here](sandbox-option.md).
**Note:** This option is currently experimental and may change or be
removed in future Electron releases.
* `disableRemote` Boolean (optional) - If set, this will disable the [`remote`](remote.md) module.
* `session` [Session](session.md#class-session) (optional) - Sets the session used by the
page. Instead of passing the Session object directly, you can also choose to
use the `partition` option instead, which accepts a partition string. When
Expand Down
39 changes: 39 additions & 0 deletions lib/browser/rpc-server.js
Expand Up @@ -261,7 +261,18 @@ const callFunction = function (event, func, caller, args) {
}
}

const isRemoteDisabled = (event) => {
if (event.sender._isRemoteDisabled()) {
event.returnValue = exceptionToMeta(event.sender, new Error('remote is disabled'))
return true
}

return false
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
if (isRemoteDisabled(event)) return

try {
event.returnValue = valueToMeta(event.sender, process.mainModule.require(module))
} catch (error) {
Expand All @@ -270,6 +281,8 @@ ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
})

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
if (isRemoteDisabled(event)) return

try {
event.returnValue = valueToMeta(event.sender, electron[module])
} catch (error) {
Expand All @@ -278,6 +291,8 @@ ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
if (isRemoteDisabled(event)) return

try {
event.returnValue = valueToMeta(event.sender, global[name])
} catch (error) {
Expand All @@ -286,6 +301,8 @@ ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
if (isRemoteDisabled(event)) return

try {
event.returnValue = valueToMeta(event.sender, event.sender.getOwnerBrowserWindow())
} catch (error) {
Expand All @@ -294,10 +311,14 @@ ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event) {
if (isRemoteDisabled(event)) return

event.returnValue = valueToMeta(event.sender, event.sender)
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
if (isRemoteDisabled(event)) return

try {
args = unwrapArgs(event.sender, args)
let constructor = objectsRegistry.get(id)
Expand All @@ -316,6 +337,8 @@ ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
if (isRemoteDisabled(event)) return

try {
args = unwrapArgs(event.sender, args)
let func = objectsRegistry.get(id)
Expand All @@ -331,6 +354,8 @@ ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
if (isRemoteDisabled(event)) return

try {
args = unwrapArgs(event.sender, args)
let object = objectsRegistry.get(id)
Expand All @@ -349,6 +374,8 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, a
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
if (isRemoteDisabled(event)) return

try {
args = unwrapArgs(event.sender, args)
let obj = objectsRegistry.get(id)
Expand All @@ -364,6 +391,8 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, args) {
if (isRemoteDisabled(event)) return

try {
args = unwrapArgs(event.sender, args)
let obj = objectsRegistry.get(id)
Expand All @@ -380,6 +409,8 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, args) {
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
if (isRemoteDisabled(event)) return

try {
let obj = objectsRegistry.get(id)

Expand All @@ -394,15 +425,21 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
if (isRemoteDisabled(event)) return

objectsRegistry.remove(event.sender.getId(), id)
})

ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (e, contextId) => {
if (isRemoteDisabled(event)) return

objectsRegistry.clear(contextId)
e.returnValue = null
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) {
if (isRemoteDisabled(event)) return

try {
let guestViewManager = require('./guest-view-manager')
event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId))
Expand All @@ -412,6 +449,8 @@ ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstance
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, requestId, guestInstanceId, method, ...args) {
if (isRemoteDisabled(event)) return

try {
let guestViewManager = require('./guest-view-manager')
let guest = guestViewManager.getGuest(guestInstanceId)
Expand Down
2 changes: 0 additions & 2 deletions lib/renderer/api/remote.js
Expand Up @@ -259,8 +259,6 @@ function metaToPlainObject (meta) {
// Construct an exception error from the meta.
function metaToException (meta) {
const error = new Error(`${meta.message}\n${meta.stack}`)
const remoteProcess = exports.process
error.from = remoteProcess ? remoteProcess.type : null
error.cause = metaToValue(meta.cause)
return error
}
Expand Down

0 comments on commit 3dcd059

Please sign in to comment.