8000 security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD by miniak · Pull Request #13031 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD #13031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 10, 2018

Conversation

miniak
Copy link
Contributor
@miniak miniak commented May 21, 2018

Follow up to #12877.
@tarruda and @MarshallOfSound please review.

It also allows different sandboxed webContents to share the renderer process (affinity) even if they have different preload scripts (as it does not have to be passed on the command line).

Checklist

@miniak miniak requested review from a team, tarruda, MarshallOfSound and juturu May 21, 2018 22:50
@miniak miniak force-pushed the miniak/sandbox-preload-path branch 2 times, most recently from 174d709 to 2c79eb5 Compare May 25, 2018 15:51
@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 2c79eb5 to 2da10ee Compare May 25, 2018 16:05
@miniak
Copy link
Contributor Author
miniak commented May 25, 2018

@zcbenz I might need some help with this. The tests are now relying on the IMHO incorrect behavior as reported in #13073. I cannot pass the preload script option via window.open in the sandboxed renderer as it's using the native implementation, which does not support passing webPreferences.

@miniak miniak force-pushed the miniak/sandbox-preload-path branch 2 times, most recently from 04dd752 to 708457e Compare May 25, 2018 17:21
@miniak
Copy link
Contributor Author
miniak commented May 25, 2018

@zcbenz When I preserve the (buggy?) preload script behavior by adding options.webPreferences.preload = webPreferences.preload to mergeBrowserWindowOptions, the tests are passing.

@codebytere codebytere changed the title Don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD for security reasons security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD May 26, 2018
@zcbenz
Copy link
Contributor
zcbenz commented May 28, 2018

@miniak I'm not familiar with the code path in sandboxed renderer at all, I don't have an answer after looking at the code.

We need a redesign of the whole WebPreferences system, currently it is inherited but with different fields filtered at different places, and some places are expecting the latest values while some places are keeping a copy of modified values.

@miniak miniak force-pushed the miniak/sandbox-preload-path branch 5 times, most recently from 284f0fc to 77498fb Compare May 29, 2018 18:39
@miniak miniak force-pushed the miniak/sandbox-preload-path branch 2 times, most recently from 37d502e to 5b37766 Compare June 6, 2018 12:29
@miniak miniak requested a review from a team June 6, 2018 12:29
Copy link
Contributor
@tarruda tarruda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good mostly, but maybe we should use a more generic solution to allow user control inheritance of parent webPreferences? A callback that happens before window creation seems fine.

command_line->AppendSwitchPath(switches::kPreloadScript, preload_path);
else
LOG(ERROR) << "preload url must be file:// protocol.";
if (!command_line->HasSwitch(switches::kEnableSandbox)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add this condition?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kEnableSandbox is about enabling the chromium sandbox, but it is not necessary for enabling sandbox mode

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarruda I can revert this part. I just wanted to avoid passing the preload script path via commandline as the sandboxed renderer is not going to use it anyway.

@@ -263,6 +263,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
When node integration is turned off, the preload script can reintroduce
Node global symbols back to the global scope. See example
[here](process.md#event-loaded).
* `inheritPreload` Boolean (optional) - Whether the preload script is inherited
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were supposed to add a more generic mechanism, like a callback that can modify webPreferences and add the preload path to the parent window.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarruda yes, but I didn't have time yet to investigate how to do it :(

@miniak miniak changed the title security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD [wip] security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD Jun 20, 2018
@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 5b37766 to 85730fb Compare July 4, 2018 11:56
@miniak miniak force-pushed the miniak/sandbox-preload-path branch 2 times, most recently from 76e4bcd to 77970f7 Compare July 31, 2018 15:16
@miniak
Copy link
Contributor Author
miniak commented Jul 31, 2018

@tarruda I finally had time to investigate how to set the preload script for the popup. I've updated the PR.

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 77970f7 to 91cf65a Compare July 31, 2018 15:23
@miniak miniak changed the title [wip] security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD security: don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD Jul 31, 2018
@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 2a1e7bc to 82a84cf Compare August 4, 2018 11:32
@miniak
Copy link
Contributor Author
miniak commented Aug 4, 2018
8000

@tarruda I had to tweak it a bit more as <webview> uses preloadURL instead of preload

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 82a84cf to db1b937 Compare August 4, 2018 11:35
platform: process.platform,
env: process.env
}
})

const getPreloadPath = function (webContents) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equivalent of the code in https://github.com/electron/electron/blob/master/atom/browser/web_contents_preferences.cc

  // The preload script.
  base::FilePath::StringType preload;
  if (GetAsString(&preference_, options::kPreloadScript, &preload)) {
    if (base::FilePath(preload).IsAbsolute())
      command_line->AppendSwitchNative(switches::kPreloadScript, preload);
    else
      LOG(ERROR) << "preload script must have absolute path.";
  } else if (GetAsString(&preference_, options::kPreloadURL, &preload)) {
    // Translate to file path if there is "preload-url" option.
    base::FilePath preload_path;
    if (net::FileURLToFilePath(GURL(preload), &preload_path))
      command_line->AppendSwitchPath(switches::kPreloadScript, preload_path);
    else
      LOG(ERROR) << "preload url must be file:// protocol.";
  }

@miniak miniak force-pushed the miniak/sandbox-preload-path branch 3 times, most recently from 29af450 to 7c719a6 Compare August 4, 2018 15:27
@miniak
Copy link
Contributor Author
miniak commented Aug 7, 2018

@MarshallOfSound is anything preventing us from merging this PR?

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 7c719a6 to 294d3fb Compare August 9, 2018 09:40
@@ -1409,6 +1409,8 @@ describe('BrowserWindow module', () => {
preload: preload
}
})
ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this IPC handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other tests are already using this IPC to configure popups

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in spec/static/main.js

ipcMain.on('set-web-preferences-on-next-new-window', (event, id, key, value) => {
  webContents.fromId(id).once('new-window', (event, url, frameName, disposition, options) => {
    options.webPreferences[key] = value
  })
})

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miniak
Copy link
Contributor Author
miniak commented Aug 9, 2018

@codebytere, @ckerr can you please review?

Copy link
Member
@ckerr ckerr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of not passing preloadPath as an argument and also the incidental cleanup that this change creates.

v8::Local<v8::Value> WebContents::GetPreloadPath(v8::Isolate* isolate) const {
base::FilePath::StringType preload;
if (auto* web_preferences = WebContentsPreferences::From(web_contents())) {
web_preferences->GetPreloadPath(&preload);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should check the retval here, something more like

if (auto* web_preferences = WebContentsPreferences::From(web_contents()) {
  if (web_preferences->GetPreloadPath(&preload)) {
    return mate::ConvertToV8(isolate, preload);
  }
}

return v8::Null(isolate);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckerr fixed

LOG(ERROR) << "preload url must be file:// protocol.";
}
if (GetPreloadPath(&preload))
command_line->AppendSwitchNative(switches::kPreloadScript, preload);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure about this? -- the removed code appends with either AppendSwitchNative or AppendSwitchPath depending on the code branch, but the new code always uses AppendSwitchNative. Is this intentional?

Copy link
Contributor Author
@miniak miniak Aug 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckerr it's ok, in preloadURL case, I return preload_path.value()

void CommandLine::AppendSwitchPath(const std::string& switch_string,
                                   const FilePath& path) {
  AppendSwitchNative(switch_string, path.value());
}

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 294d3fb to c5efac7 Compare August 9, 2018 21:20
Copy link
Member
@ckerr ckerr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. On second read I see a couple of small things that could be better but no blockers.

@@ -1884,6 +1884,16 @@ void WebContents::OnGetZoomLevel(content::RenderFrameHost* rfh,
rfh->Send(reply_msg);
}

v8::Local<v8::Value> WebContents::GetPreloadPath(v8::Isolate* isolate) const {
base::FilePath::StringType preload;
if (auto* web_preferences = WebContentsPreferences::From(web_contents())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(trivial) declaration of preload could be moved inside this if { clause

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckerr done

@@ -440,7 +440,8 @@ ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
event.returnValue = null
})

ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event, preloadPath) {
ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event) {
const preloadPath = event.sender._getPreloadPath()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we're in the neighborhood, the code below this

   event.returnValue = {
     preloadSrc: preloadSrc,
     preloadError: preloadError,
     ...

could be updated to use ES6 enhanced object literals:

   event.returnValue = {
     preloadSrc,
     preloadError,
     ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckerr done

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from c5efac7 to 3fa4294 Compare August 9, 2018 21:54
@ckerr
Copy link
Member
ckerr commented Aug 9, 2018

@miniak, thanks for the quick changes!

Somewhere along the line atom/browser/api/atom_api_web_contents.ccpicked up conflicts with master. Could you resolve those?

@miniak miniak force-pushed the miniak/sandbox-preload-path branch from 3fa4294 to 5636536 Compare August 9, 2018 22:39
@miniak
Copy link
Contributor Author
miniak commented Aug 9, 2018

@ckerr rebased + conflict resolved

@ckerr ckerr merged commit 702cc84 into master Aug 10, 2018
@ckerr ckerr deleted the miniak/sandbox-preload-path branch August 10, 2018 22:19
@trop
Copy link
Contributor
trop bot commented Aug 10, 2018

An error occurred while attempting to backport this PR to "3-0-x", you will need to perform this backport manually

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
77D1
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0