feat: only allow bundled preload scripts (#17308)

This commit is contained in:
Milan Burda 2019-03-28 11:38:51 +01:00 committed by Alexey Kuzmin
parent 3d307e5610
commit 8cf15cc931
11 changed files with 79 additions and 3 deletions

View file

@ -3,6 +3,7 @@
const electron = require('electron')
const { EventEmitter } = require('events')
const fs = require('fs')
const path = require('path')
const util = require('util')
const v8Util = process.electronBinding('v8_util')
@ -19,6 +20,7 @@ const guestViewManager = require('@electron/internal/browser/guest-view-manager'
const bufferUtils = require('@electron/internal/common/buffer-utils')
const errorUtils = require('@electron/internal/common/error-utils')
const clipboardUtils = require('@electron/internal/common/clipboard-utils')
const { isParentDir } = require('@electron/internal/common/path-utils')
const hasProp = {}.hasOwnProperty
@ -498,12 +500,24 @@ ipcMainUtils.handle('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...ar
})
const readFile = util.promisify(fs.readFile)
const realpath = util.promisify(fs.realpath)
let absoluteAppPath
const getAppPath = async function () {
if (absoluteAppPath === undefined) {
absoluteAppPath = await realpath(electron.app.getAppPath())
}
return absoluteAppPath
}
const getPreloadScript = async function (preloadPath) {
let preloadSrc = null
let preloadError = null
if (preloadPath) {
try {
if (!isParentDir(await getAppPath(), await realpath(preloadPath))) {
throw new Error('Preload scripts outside of app path are not allowed')
}
preloadSrc = (await readFile(preloadPath)).toString()
} catch (err) {
preloadError = errorUtils.serialize(err)

6
lib/common/path-utils.ts Normal file
View file

@ -0,0 +1,6 @@
import * as path from 'path'
export const isParentDir = function (parent: string, dir: string) {
const relative = path.relative(parent, dir)
return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative)
}

View file

@ -1,4 +1,5 @@
import { EventEmitter } from 'events'
import * as fs from 'fs'
import * as path from 'path'
const Module = require('module')
@ -160,10 +161,22 @@ if (nodeIntegration) {
}
const errorUtils = require('@electron/internal/common/error-utils')
const { isParentDir } = require('@electron/internal/common/path-utils')
let absoluteAppPath: string
const getAppPath = function () {
if (absoluteAppPath === undefined) {
absoluteAppPath = fs.realpathSync(appPath!)
}
return absoluteAppPath
}
// Load the preload scripts.
for (const preloadScript of preloadScripts) {
try {
if (!isParentDir(getAppPath(), fs.realpathSync(preloadScript))) {
throw new Error('Preload scripts outside of app path are not allowed')
}
require(preloadScript)
} catch (error) {
console.error(`Unable to load preload script: ${preloadScript}`)