enable speedy sandbox mode by default (#2320)

This commit is contained in:
Kuitos 2022-10-30 19:37:58 +08:00 committed by GitHub
parent 6544b17f9b
commit 743473ae51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 85 deletions

View File

@ -11,8 +11,9 @@ writeFileSync(versionFilePath, `export const version = '${version}';`);
const globalsFilePath = join(__dirname, './src/sandbox/globals.ts');
writeFileSync(
globalsFilePath,
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
export const globals = ${JSON.stringify(Object.keys(globals.builtin), null, 2)};`,
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
// only init its values while Proxy is supported
export const globals = window.Proxy ? ${JSON.stringify(Object.keys(globals.es2015), null, 2)} : [];`,
);
export default {

View File

@ -75,6 +75,9 @@ type QiankunSpecialOpts = {
* @deprecated We use strict mode by default
*/
loose?: boolean;
/**
* use speed sandbox mode, enabled by default from 2.9.0
*/
speedy?: boolean;
patchers?: Patcher[];
};

View File

@ -18,7 +18,7 @@ import type {
ObjectType,
} from './interfaces';
import { createSandboxContainer, css } from './sandbox';
import { lexicalGlobals } from './sandbox/common';
import { trustedGlobals } from './sandbox/common';
import {
Deferred,
genAppInstanceIdByName,
@ -311,7 +311,8 @@ export async function loadApp<T extends ObjectType>(
let mountSandbox = () => Promise.resolve();
let unmountSandbox = () => Promise.resolve();
const useLooseSandbox = typeof sandbox === 'object' && !!sandbox.loose;
const speedySandbox = typeof sandbox === 'object' && !!sandbox.speedy;
// enable speedy mode by default
const speedySandbox = typeof sandbox === 'object' ? sandbox.speedy !== false : true;
let sandboxContainer;
if (sandbox) {
sandboxContainer = createSandboxContainer(
@ -342,7 +343,7 @@ export async function loadApp<T extends ObjectType>(
// get the lifecycle hooks from module exports
const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, {
scopedGlobalVariables: speedySandbox ? lexicalGlobals : [],
scopedGlobalVariables: speedySandbox ? trustedGlobals : [],
});
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
scriptExports,

View File

@ -18,13 +18,12 @@ export function getCurrentRunningApp() {
}
export function setCurrentRunningApp(appInstance: { name: string; window: WindowProxy } | null) {
// set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
// Set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
currentRunningApp = appInstance;
}
const scopedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
export const unscopedGlobals = [...without(globals, ...scopedGlobals), 'requestAnimationFrame'];
export const lexicalGlobals = [...unscopedGlobals, ...scopedGlobals];
const spiedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
export const trustedGlobals = [...without(globals, ...spiedGlobals), 'requestAnimationFrame'];
const functionBoundedValueMap = new WeakMap<CallableFunction, CallableFunction>();

View File

@ -1,69 +1,63 @@
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
export const globals = [
'AggregateError',
'Array',
'ArrayBuffer',
'Atomics',
'BigInt',
'BigInt64Array',
'BigUint64Array',
'Boolean',
'constructor',
'DataView',
'Date',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
'Error',
'escape',
'eval',
'EvalError',
'FinalizationRegistry',
'Float32Array',
'Float64Array',
'Function',
'globalThis',
'hasOwnProperty',
'Infinity',
'Int16Array',
'Int32Array',
'Int8Array',
'isFinite',
'isNaN',
'isPrototypeOf',
'JSON',
'Map',
'Math',
'NaN',
'Number',
'Object',
'parseFloat',
'parseInt',
'Promise',
'propertyIsEnumerable',
'Proxy',
'RangeError',
'ReferenceError',
'Reflect',
'RegExp',
'Set',
'SharedArrayBuffer',
'String',
'Symbol',
'SyntaxError',
'toLocaleString',
'toString',
'TypeError',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'undefined',
'unescape',
'URIError',
'valueOf',
'WeakMap',
'WeakRef',
'WeakSet',
];
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
// only init its values while Proxy is supported
export const globals = window.Proxy
? [
'Array',
'ArrayBuffer',
'Boolean',
'constructor',
'DataView',
'Date',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
'Error',
'escape',
'eval',
'EvalError',
'Float32Array',
'Float64Array',
'Function',
'hasOwnProperty',
'Infinity',
'Int16Array',
'Int32Array',
'Int8Array',
'isFinite',
'isNaN',
'isPrototypeOf',
'JSON',
'Map',
'Math',
'NaN',
'Number',
'Object',
'parseFloat',
'parseInt',
'Promise',
'propertyIsEnumerable',
'Proxy',
'RangeError',
'ReferenceError',
'Reflect',
'RegExp',
'Set',
'String',
'Symbol',
'SyntaxError',
'toLocaleString',
'toString',
'TypeError',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'undefined',
'unescape',
'URIError',
'valueOf',
'WeakMap',
'WeakSet',
]
: [];

View File

@ -6,7 +6,7 @@ import { execScripts } from 'import-html-entry';
import { isFunction } from 'lodash';
import { frameworkConfiguration } from '../../../apis';
import { qiankunHeadTagName } from '../../../utils';
import { lexicalGlobals } from '../../common';
import { trustedGlobals } from '../../common';
import * as css from '../css';
export const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
@ -280,7 +280,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
const { fetch } = frameworkConfiguration;
const referenceNode = mountDOM.contains(refChild) ? refChild : null;
const scopedGlobalVariables = speedySandbox ? lexicalGlobals : [];
const scopedGlobalVariables = speedySandbox ? trustedGlobals : [];
if (src) {
execScripts(null, [src], proxy, {

View File

@ -6,7 +6,7 @@
import type { SandBox } from '../interfaces';
import { SandBoxType } from '../interfaces';
import { isPropertyFrozen, nativeGlobal, nextTask } from '../utils';
import { getCurrentRunningApp, getTargetValue, setCurrentRunningApp, unscopedGlobals } from './common';
import { getCurrentRunningApp, getTargetValue, trustedGlobals, setCurrentRunningApp } from './common';
type SymbolTarget = 'target' | 'globalContext';
@ -49,7 +49,7 @@ const globalVariableWhiteList: string[] = [
variables who are impossible to be overwritten need to be escaped from proxy sandbox for performance reasons
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables
*/
const unscopables = unscopedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });
const unscopables = trustedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });
const useNativeWindowForBindingsProps = new Map<PropertyKey, boolean>([
['fetch', true],
@ -132,9 +132,6 @@ export default class ProxySandbox implements SandBox {
sandboxRunning = true;
latestSetProp: PropertyKey | null = null;
// the descriptor of global variables in whitelist before it been modified
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};
active() {
if (!this.sandboxRunning) activeSandboxCount++;
this.sandboxRunning = true;
@ -163,6 +160,8 @@ export default class ProxySandbox implements SandBox {
this.sandboxRunning = false;
}
// the descriptor of global variables in whitelist before it been modified
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};
globalContext: typeof window;
constructor(name: string, globalContext = window) {