Merge branch 'check-sender-web-contents-access'

This commit is contained in:
Kevin Sawicki 2016-11-23 12:30:25 -08:00
commit 2cabfa5589
2 changed files with 82 additions and 14 deletions

View file

@ -138,10 +138,7 @@ const createGuest = function (embedder, url, frameName, options, postData) {
return setupGuest(embedder, frameName, guest, options) return setupGuest(embedder, frameName, guest, options)
} }
const getGuestWindow = function (guestId) { const getGuestWindow = function (guestContents) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
let guestWindow = BrowserWindow.fromWebContents(guestContents) let guestWindow = BrowserWindow.fromWebContents(guestContents)
if (guestWindow == null) { if (guestWindow == null) {
const hostContents = guestContents.hostWebContents const hostContents = guestContents.hostWebContents
@ -187,27 +184,35 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, fr
}) })
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function (event, guestId) { ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function (event, guestId) {
const guestWindow = getGuestWindow(guestId) const guestContents = webContents.fromId(guestId)
if (guestWindow == null) return if (guestContents == null) return
if (canAccessWindow(event.sender, guestWindow.webContents)) { if (!canAccessWindow(event.sender, guestContents)) {
guestWindow.destroy()
} else {
console.error(`Blocked ${event.sender.getURL()} from closing its opener.`) console.error(`Blocked ${event.sender.getURL()} from closing its opener.`)
return
} }
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) guestWindow.destroy()
}) })
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) { ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) {
const guestWindow = getGuestWindow(guestId) const guestContents = webContents.fromId(guestId)
if (guestWindow == null) { if (guestContents == null) {
event.returnValue = null event.returnValue = null
return return
} }
if (canAccessWindow(event.sender, guestWindow.webContents)) { if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null
return
}
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) {
event.returnValue = guestWindow[method].apply(guestWindow, args) event.returnValue = guestWindow[method].apply(guestWindow, args)
} else { } else {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null event.returnValue = null
} }
}) })

View file

@ -313,7 +313,7 @@ describe('chromium feature', function () {
}) })
}) })
describe('window.opener security', function () { describe('window.opener access from BrowserWindow', function () {
this.timeout(10000) this.timeout(10000)
const scheme = 'other' const scheme = 'other'
@ -355,6 +355,69 @@ describe('chromium feature', function () {
}) })
}) })
describe('window.opener access from <webview>', function () {
this.timeout(10000)
const scheme = 'other'
const srcPath = `${fixtures}/pages/webview-opener-postMessage.html`
const pageURL = `file://${fixtures}/pages/window-opener-location.html`
let webview = null
before(function (done) {
protocol.registerFileProtocol(scheme, function (request, callback) {
callback(srcPath)
}, function (error) {
done(error)
})
})
after(function () {
protocol.unregisterProtocol(scheme)
})
afterEach(function () {
if (webview != null) webview.remove()
})
it('does nothing when origin of webview src URL does not match opener', function (done) {
webview = new WebView()
webview.addEventListener('console-message', function (e) {
assert.equal(e.message, 'null')
done()
})
webview.setAttribute('allowpopups', 'on')
webview.src = url.format({
pathname: srcPath,
protocol: scheme,
query: {
p: pageURL
},
slashes: true
})
document.body.appendChild(webview)
})
it('works when origin does not match opener but has node integration', function (done) {
webview = new WebView()
webview.addEventListener('console-message', function (e) {
webview.remove()
assert.equal(e.message, location.href)
done()
})
webview.setAttribute('allowpopups', 'on')
webview.setAttribute('nodeintegration', 'on')
webview.src = url.format({
pathname: srcPath,
protocol: scheme,
query: {
p: pageURL
},
slashes: true
})
document.body.appendChild(webview)
})
})
describe('window.postMessage', function () { describe('window.postMessage', function () {
it('sets the source and origin correctly', function (done) { it('sets the source and origin correctly', function (done) {
var b, sourceId var b, sourceId