fix: set nativeWindowOpen when sandboxed (#18273)
This commit is contained in:
parent
4ed989587b
commit
ac002b3c3c
6 changed files with 44 additions and 24 deletions
|
@ -609,11 +609,6 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||||
|
|
||||||
int opener_render_process_id = opener->GetProcess()->GetID();
|
int opener_render_process_id = opener->GetProcess()->GetID();
|
||||||
|
|
||||||
if (IsRendererSandboxed(opener_render_process_id)) {
|
|
||||||
*no_javascript_access = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
|
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
|
||||||
if (RendererDisablesPopups(opener_render_process_id)) {
|
if (RendererDisablesPopups(opener_render_process_id)) {
|
||||||
// <webview> without allowpopups attribute should return
|
// <webview> without allowpopups attribute should return
|
||||||
|
|
|
@ -147,6 +147,8 @@ WebContentsPreferences::WebContentsPreferences(
|
||||||
#endif
|
#endif
|
||||||
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
||||||
|
|
||||||
|
SetDefaults();
|
||||||
|
|
||||||
// If this is a <webview> tag, and the embedder is offscreen-rendered, then
|
// If this is a <webview> tag, and the embedder is offscreen-rendered, then
|
||||||
// this WebContents is also offscreen-rendered.
|
// this WebContents is also offscreen-rendered.
|
||||||
int guest_instance_id = 0;
|
int guest_instance_id = 0;
|
||||||
|
@ -172,6 +174,12 @@ WebContentsPreferences::~WebContentsPreferences() {
|
||||||
instances_.end());
|
instances_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContentsPreferences::SetDefaults() {
|
||||||
|
if (IsEnabled(options::kSandbox)) {
|
||||||
|
SetBool(options::kNativeWindowOpen, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||||
const base::StringPiece& key,
|
const base::StringPiece& key,
|
||||||
bool val) {
|
bool val) {
|
||||||
|
@ -185,6 +193,10 @@ bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContentsPreferences::SetBool(const base::StringPiece& key, bool value) {
|
||||||
|
preference_.SetKey(key, base::Value(value));
|
||||||
|
}
|
||||||
|
|
||||||
bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||||
bool default_value) const {
|
bool default_value) const {
|
||||||
auto* current_value =
|
auto* current_value =
|
||||||
|
@ -197,6 +209,8 @@ bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||||
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
||||||
if (preference_.is_dict())
|
if (preference_.is_dict())
|
||||||
static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend);
|
static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend);
|
||||||
|
|
||||||
|
SetDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentsPreferences::Clear() {
|
void WebContentsPreferences::Clear() {
|
||||||
|
|
|
@ -36,6 +36,9 @@ class WebContentsPreferences
|
||||||
const mate::Dictionary& web_preferences);
|
const mate::Dictionary& web_preferences);
|
||||||
~WebContentsPreferences() override;
|
~WebContentsPreferences() override;
|
||||||
|
|
||||||
|
// Set WebPreferences defaults onto the JS object.
|
||||||
|
void SetDefaults();
|
||||||
|
|
||||||
// A simple way to know whether a Boolean property is enabled.
|
// A simple way to know whether a Boolean property is enabled.
|
||||||
bool IsEnabled(const base::StringPiece& name,
|
bool IsEnabled(const base::StringPiece& name,
|
||||||
bool default_value = false) const;
|
bool default_value = false) const;
|
||||||
|
@ -75,6 +78,9 @@ class WebContentsPreferences
|
||||||
// Set preference value to given bool if user did not provide value
|
// Set preference value to given bool if user did not provide value
|
||||||
bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val);
|
bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val);
|
||||||
|
|
||||||
|
// Set preference value to given bool
|
||||||
|
void SetBool(const base::StringPiece& key, bool value);
|
||||||
|
|
||||||
static std::vector<WebContentsPreferences*> instances_;
|
static std::vector<WebContentsPreferences*> instances_;
|
||||||
|
|
||||||
content::WebContents* web_contents_;
|
content::WebContents* web_contents_;
|
||||||
|
|
|
@ -112,7 +112,6 @@ const createGuest = function (embedder, params) {
|
||||||
}
|
}
|
||||||
this.loadURL(params.src, opts)
|
this.loadURL(params.src, opts)
|
||||||
}
|
}
|
||||||
guest.allowPopups = params.allowpopups
|
|
||||||
embedder.emit('did-attach-webview', event, guest)
|
embedder.emit('did-attach-webview', event, guest)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -207,6 +206,7 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||||
enableRemoteModule: params.enableremotemodule,
|
enableRemoteModule: params.enableremotemodule,
|
||||||
plugins: params.plugins,
|
plugins: params.plugins,
|
||||||
zoomFactor: embedder.getZoomFactor(),
|
zoomFactor: embedder.getZoomFactor(),
|
||||||
|
disablePopups: !params.allowpopups,
|
||||||
webSecurity: !params.disablewebsecurity,
|
webSecurity: !params.disablewebsecurity,
|
||||||
enableBlinkFeatures: params.blinkfeatures,
|
enableBlinkFeatures: params.blinkfeatures,
|
||||||
disableBlinkFeatures: params.disableblinkfeatures
|
disableBlinkFeatures: params.disableblinkfeatures
|
||||||
|
@ -228,11 +228,6 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||||
webPreferences.preloadURL = params.preload
|
webPreferences.preloadURL = params.preload
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return null from native window.open if allowpopups is unset
|
|
||||||
if (webPreferences.nativeWindowOpen === true && !params.allowpopups) {
|
|
||||||
webPreferences.disablePopups = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security options that guest will always inherit from embedder
|
// Security options that guest will always inherit from embedder
|
||||||
const inheritedWebPreferences = new Map([
|
const inheritedWebPreferences = new Map([
|
||||||
['contextIsolation', true],
|
['contextIsolation', true],
|
||||||
|
|
|
@ -244,7 +244,7 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
|
||||||
options = mergeBrowserWindowOptions(event.sender, options)
|
options = mergeBrowserWindowOptions(event.sender, options)
|
||||||
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
|
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
|
||||||
const { newGuest } = event
|
const { newGuest } = event
|
||||||
if ((event.sender.getType() === 'webview' && !event.sender.allowPopups) || event.defaultPrevented) {
|
if ((event.sender.getType() === 'webview' && event.sender.getLastWebPreferences().disablePopups) || event.defaultPrevented) {
|
||||||
if (newGuest != null) {
|
if (newGuest != null) {
|
||||||
if (options.webContents === newGuest.webContents) {
|
if (options.webContents === newGuest.webContents) {
|
||||||
// the webContents is not changed, so set defaultPrevented to false to
|
// the webContents is not changed, so set defaultPrevented to false to
|
||||||
|
|
|
@ -545,20 +545,30 @@ describe('<webview> tag', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('allowpopups attribute', () => {
|
describe('allowpopups attribute', () => {
|
||||||
it('can not open new window when not set', async () => {
|
const generateSpecs = (description, webpreferences = '') => {
|
||||||
const message = await startLoadingWebViewAndWaitForMessage(webview, {
|
describe(description, () => {
|
||||||
src: `file://${fixtures}/pages/window-open-hide.html`
|
it('can not open new window when not set', async () => {
|
||||||
})
|
const message = await startLoadingWebViewAndWaitForMessage(webview, {
|
||||||
expect(message).to.equal('null')
|
webpreferences,
|
||||||
})
|
src: `file://${fixtures}/pages/window-open-hide.html`
|
||||||
|
})
|
||||||
|
expect(message).to.equal('null')
|
||||||
|
})
|
||||||
|
|
||||||
it('can open new window when set', async () => {
|
it('can open new window when set', async () => {
|
||||||
const message = await startLoadingWebViewAndWaitForMessage(webview, {
|
const message = await startLoadingWebViewAndWaitForMessage(webview, {
|
||||||
allowpopups: 'on',
|
webpreferences,
|
||||||
src: `file://${fixtures}/pages/window-open-hide.html`
|
allowpopups: 'on',
|
||||||
|
src: `file://${fixtures}/pages/window-open-hide.html`
|
||||||
|
})
|
||||||
|
expect(message).to.equal('window')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
expect(message).to.equal('window')
|
}
|
||||||
})
|
|
||||||
|
generateSpecs('without sandbox')
|
||||||
|
generateSpecs('with sandbox', 'sandbox=yes')
|
||||||
|
generateSpecs('with nativeWindowOpen', 'nativeWindowOpen=yes')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('webpreferences attribute', () => {
|
describe('webpreferences attribute', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue