Jelajahi Sumber

refactor: simplify safe-globals and createNullObj

tophf 3 tahun lalu
induk
melakukan
c16eefc53d

+ 7 - 7
.eslintrc.js

@@ -14,21 +14,21 @@ const FILES_SHARED = [
 ];
 ];
 
 
 const GLOBALS_COMMON = {
 const GLOBALS_COMMON = {
-  ...getGlobals('src/common/safe-globals.js'),
+  ...getGlobals('common'),
   re: false, // transform-modern-regexp with useRe option
   re: false, // transform-modern-regexp with useRe option
 };
 };
 const GLOBALS_INJECTED = {
 const GLOBALS_INJECTED = {
-  ...getGlobals(`src/injected/safe-globals-injected.js`),
+  ...getGlobals('injected'),
   PAGE_MODE_HANDSHAKE: false,
   PAGE_MODE_HANDSHAKE: false,
   VAULT_ID: false,
   VAULT_ID: false,
 };
 };
 const GLOBALS_CONTENT = {
 const GLOBALS_CONTENT = {
   INIT_FUNC_NAME: false,
   INIT_FUNC_NAME: false,
-  ...getGlobals(`src/injected/content/safe-globals-content.js`),
+  ...getGlobals('injected/content'),
   ...GLOBALS_INJECTED,
   ...GLOBALS_INJECTED,
 };
 };
 const GLOBALS_WEB = {
 const GLOBALS_WEB = {
-  ...getGlobals(`src/injected/web/safe-globals-web.js`),
+  ...getGlobals('injected/web'),
   ...GLOBALS_INJECTED,
   ...GLOBALS_INJECTED,
   IS_FIREFOX: false, // passed as a parameter to VMInitInjection in webpack.conf.js
   IS_FIREFOX: false, // passed as a parameter to VMInitInjection in webpack.conf.js
 };
 };
@@ -54,7 +54,7 @@ const INJECTED_RULES = {
     }, {
     }, {
       selector: `CallExpression[callee.name="defineProperty"]:not(${[
       selector: `CallExpression[callee.name="defineProperty"]:not(${[
         '[arguments.2.properties.0.key.name="__proto__"]',
         '[arguments.2.properties.0.key.name="__proto__"]',
-        ':has(CallExpression[callee.name="createNullObj"])'
+        ':has(CallExpression[callee.name="nullObjFrom"])'
       ].join(',')})`,
       ].join(',')})`,
       message: 'Prototype of descriptor may be spoofed/broken in an unsafe environment',
       message: 'Prototype of descriptor may be spoofed/broken in an unsafe environment',
     }
     }
@@ -156,9 +156,9 @@ module.exports = {
   },
   },
 };
 };
 
 
-function getGlobals(filename) {
+function getGlobals(path) {
   const res = {};
   const res = {};
-  const { ast } = readGlobalsFile(filename, { ast: true });
+  const { ast } = readGlobalsFile(path, { ast: true });
   ast.program.body.forEach(body => {
   ast.program.body.forEach(body => {
     const { declarations } = body.declaration || body;
     const { declarations } = body.declaration || body;
     if (!declarations) return;
     if (!declarations) return;

+ 1 - 1
package.json

@@ -15,7 +15,7 @@
     "lint:js": "eslint --ext .js,.vue . --cache",
     "lint:js": "eslint --ext .js,.vue . --cache",
     "lint:yml": "gulp check",
     "lint:yml": "gulp check",
     "svgo": "plaid svgo",
     "svgo": "plaid svgo",
-    "test": "cross-env BABEL_ENV=test jest test",
+    "test": "cross-env BABEL_ENV=test TEST=test jest test",
     "ci": "run-p lint test",
     "ci": "run-p lint test",
     "bumpVersion": "gulp bump",
     "bumpVersion": "gulp bump",
     "bump": "run-s ci \"bumpVersion --commit\"",
     "bump": "run-s ci \"bumpVersion --commit\"",

+ 5 - 12
scripts/webpack-util.js

@@ -4,17 +4,9 @@ const WrapperWebpackPlugin = require('wrapper-webpack-plugin');
 
 
 // {entryName: path}
 // {entryName: path}
 const entryGlobals = {
 const entryGlobals = {
-  common: [
-    './src/common/safe-globals.js',
-  ],
-  'injected/content': [
-    './src/injected/safe-globals-injected.js',
-    './src/injected/content/safe-globals-content.js',
-  ],
-  'injected/web': [
-    './src/injected/safe-globals-injected.js',
-    './src/injected/web/safe-globals-web.js',
-  ],
+  'common': ['common'],
+  'injected/content': ['injected', 'injected/content'],
+  'injected/web': ['injected', 'injected/web'],
 };
 };
 
 
 /**
 /**
@@ -59,8 +51,9 @@ function getUniqIdB64() {
   ).toString('base64');
   ).toString('base64');
 }
 }
 
 
-function readGlobalsFile(filename, babelOpts = {}) {
+function readGlobalsFile(path, babelOpts = {}) {
   const { ast, code = !ast } = babelOpts;
   const { ast, code = !ast } = babelOpts;
+  const filename = `./src/${path}/safe-globals.js`;
   const src = fs.readFileSync(filename, { encoding: 'utf8' })
   const src = fs.readFileSync(filename, { encoding: 'utf8' })
   .replace(/\bexport\s+(function\s+(\w+))/g, 'const $2 = $1')
   .replace(/\bexport\s+(function\s+(\w+))/g, 'const $2 = $1')
   .replace(/\bexport\s+(?=(const|let)\s)/g, '');
   .replace(/\bexport\s+(?=(const|let)\s)/g, '');

+ 1 - 0
scripts/webpack.conf.js

@@ -78,6 +78,7 @@ const defsObj = {
   'process.env.INIT_FUNC_NAME': JSON.stringify(INIT_FUNC_NAME),
   'process.env.INIT_FUNC_NAME': JSON.stringify(INIT_FUNC_NAME),
   'process.env.CODEMIRROR_THEMES': JSON.stringify(getCodeMirrorThemes()),
   'process.env.CODEMIRROR_THEMES': JSON.stringify(getCodeMirrorThemes()),
   'process.env.DEV': JSON.stringify(!isProd),
   'process.env.DEV': JSON.stringify(!isProd),
+  'process.env.TEST': JSON.stringify(process.env.BABEL_ENV === 'test'),
 };
 };
 // avoid running webpack bootstrap in a potentially hacked environment
 // avoid running webpack bootstrap in a potentially hacked environment
 // after documentElement was replaced which triggered reinjection of content scripts
 // after documentElement was replaced which triggered reinjection of content scripts

+ 1 - 1
src/injected/content/gm-api-content.js

@@ -62,6 +62,6 @@ export async function sendSetPopup(isDelayed) {
       await setPopupThrottle;
       await setPopupThrottle;
       setPopupThrottle = null;
       setPopupThrottle = null;
     }
     }
-    sendCmd('SetPopup', createNullObj({ menus }, bridge, ['ids', INJECT_INTO]));
+    sendCmd('SetPopup', safePickInto({ menus }, bridge, ['ids', INJECT_INTO]));
   }
   }
 }
 }

+ 7 - 6
src/injected/content/requests.js

@@ -13,6 +13,10 @@ const getBlobType = describeProperty(BlobProto, 'type').get;
 const getReaderResult = describeProperty(SafeFileReader[PROTO], 'result').get;
 const getReaderResult = describeProperty(SafeFileReader[PROTO], 'result').get;
 const readAsDataURL = SafeFileReader[PROTO].readAsDataURL;
 const readAsDataURL = SafeFileReader[PROTO].readAsDataURL;
 const fdAppend = SafeFormData[PROTO].append;
 const fdAppend = SafeFormData[PROTO].append;
+const PROPS_TO_COPY = [
+  'events',
+  'fileName',
+];
 /** @type {GMReq.Content} */
 /** @type {GMReq.Content} */
 const requests = createNullObj();
 const requests = createNullObj();
 let downloadChain = promiseResolve();
 let downloadChain = promiseResolve();
@@ -26,13 +30,10 @@ addHandlers({
    */
    */
   async HttpRequest(msg, realm) {
   async HttpRequest(msg, realm) {
     /** @type {GMReq.Content} */
     /** @type {GMReq.Content} */
-    requests[msg.id] = createNullObj({
+    requests[msg.id] = safePickInto({
       realm,
       realm,
       wantsBlob: msg.xhrType === 'blob',
       wantsBlob: msg.xhrType === 'blob',
-    }, msg, [
-      'events',
-      'fileName',
-    ]);
+    }, msg, PROPS_TO_COPY);
     msg.url = getFullUrl(msg.url);
     msg.url = getFullUrl(msg.url);
     let { data } = msg;
     let { data } = msg;
     if (data[1] && !IS_FIREFOX /* in FF FormData is recreated in bg::decodeBody */) {
     if (data[1] && !IS_FIREFOX /* in FF FormData is recreated in bg::decodeBody */) {
@@ -139,7 +140,7 @@ async function revokeBlobAfterTimeout(url) {
  * @return {Promise<Blob|ArrayBuffer>}
  * @return {Promise<Blob|ArrayBuffer>}
  */
  */
 function receiveAllChunks(req, msg) {
 function receiveAllChunks(req, msg) {
-  pickIntoNullObj(req, msg, ['dataSize', 'contentType']);
+  safePickInto(req, msg, ['dataSize', 'contentType']);
   req.arr = new SafeUint8Array(req.dataSize);
   req.arr = new SafeUint8Array(req.dataSize);
   processChunk(req, msg.data.response, 0);
   processChunk(req, msg.data.response, 0);
   return !req.gotChunks
   return !req.gotChunks

+ 4 - 1
src/injected/content/safe-globals-content.js → src/injected/content/safe-globals.js

@@ -33,11 +33,14 @@ export const { charCodeAt, indexOf: stringIndexOf, slice } = '';
 export const { append, appendChild, attachShadow, remove, setAttribute } = Element[PROTO];
 export const { append, appendChild, attachShadow, remove, setAttribute } = Element[PROTO];
 export const {
 export const {
   assign,
   assign,
+  create: objectCreate,
   defineProperty,
   defineProperty,
   getOwnPropertyDescriptor: describeProperty,
   getOwnPropertyDescriptor: describeProperty,
   getPrototypeOf,
   getPrototypeOf,
   keys: objectKeys,
   keys: objectKeys,
 } = Object;
 } = Object;
+// eslint-disable-next-line no-restricted-syntax
+export const createNullObj = Object.create.bind(Object, null);
 export const { random: mathRandom } = Math;
 export const { random: mathRandom } = Math;
 export const regexpTest = RegExp[PROTO].test;
 export const regexpTest = RegExp[PROTO].test;
 export const { toStringTag: toStringTagSym } = Symbol; // used by ProtectWebpackBootstrapPlugin
 export const { toStringTag: toStringTagSym } = Symbol; // used by ProtectWebpackBootstrapPlugin
@@ -47,7 +50,7 @@ export const { get: getHref } = describeProperty(HTMLAnchorElement[PROTO], 'href
 export const getDetail = describeProperty(SafeCustomEvent[PROTO], 'detail').get;
 export const getDetail = describeProperty(SafeCustomEvent[PROTO], 'detail').get;
 export const getRelatedTarget = describeProperty(SafeMouseEvent[PROTO], 'relatedTarget').get;
 export const getRelatedTarget = describeProperty(SafeMouseEvent[PROTO], 'relatedTarget').get;
 export const getReadyState = describeProperty(Document[PROTO], 'readyState').get;
 export const getReadyState = describeProperty(Document[PROTO], 'readyState').get;
-export const logging = assign(createNullObj(), console);
+export const logging = nullObjFrom(console);
 export const { chrome } = global;
 export const { chrome } = global;
 export const VM_UUID = chrome.runtime.getURL('');
 export const VM_UUID = chrome.runtime.getURL('');
 /** Unlike the built-in `instanceof` operator this doesn't call @@hasInstance which may be spoofed */
 /** Unlike the built-in `instanceof` operator this doesn't call @@hasInstance which may be spoofed */

+ 11 - 24
src/injected/safe-globals-injected.js → src/injected/safe-globals.js

@@ -1,7 +1,7 @@
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-unused-vars */
 
 
 /**
 /**
- * This file is used by both `injected` and `injected-web` entries.
+ * This file runs before safe-globals of `injected-content` and `injected-web` entries.
  * `global` is used instead of WebPack's polyfill which we disable in webpack.conf.js.
  * `global` is used instead of WebPack's polyfill which we disable in webpack.conf.js.
  * `export` is stripped in the final output and is only used for our NodeJS test scripts.
  * `export` is stripped in the final output and is only used for our NodeJS test scripts.
  * WARNING! Don't use exported functions from @/common anywhere in injected!
  * WARNING! Don't use exported functions from @/common anywhere in injected!
@@ -58,9 +58,15 @@ export const setOwnProp = (obj, key, value, mutable = true, valueKey) => (
   })
   })
 );
 );
 
 
-/** `dst` must have a null proto */
-export const pickIntoNullObj = (dst, src, keys) => {
-  if (process.env.DEBUG) throwIfProtoPresent(dst);
+export const nullObjFrom = src => process.env.TEST
+  ? global.Object.assign({ __proto__: null }, src)
+  : assign(createNullObj(), src);
+
+/** If `dst` has a proto, it'll be copied into a new proto:null object */
+export const safePickInto = (dst, src, keys) => {
+  if (getPrototypeOf(dst)) {
+    dst = nullObjFrom(dst);
+  }
   if (src) {
   if (src) {
     keys::forEach(key => {
     keys::forEach(key => {
       if (hasOwnProperty(src, key)) {
       if (hasOwnProperty(src, key)) {
@@ -71,25 +77,6 @@ export const pickIntoNullObj = (dst, src, keys) => {
   return dst;
   return dst;
 };
 };
 
 
-/**
- * Helps avoid interception via `Object.prototype`.
- * @param {Object} [base] - source object to copy as a null-proto object
- * @param {Object} [src] - source object to pick from
- * @param {string[]} [keys] - all keys will be picked otherwise
- * @returns {Object} `base` if it's already without prototype, a new object otherwise
- */
-export const createNullObj = (base, src, keys) => {
-  const res = { __proto__: null };
-  if (base) {
-    assign(res, base);
-  }
-  if (src) {
-    if (keys) pickIntoNullObj(res, src, keys);
-    else assign(res, src);
-  }
-  return res;
-};
-
 // WARNING! `obj` must use __proto__:null
 // WARNING! `obj` must use __proto__:null
 export const ensureNestedProp = (obj, bucketId, key, defaultValue) => {
 export const ensureNestedProp = (obj, bucketId, key, defaultValue) => {
   if (process.env.DEBUG) throwIfProtoPresent(obj);
   if (process.env.DEBUG) throwIfProtoPresent(obj);
@@ -121,7 +108,7 @@ export const log = (level, ...args) => {
  * invalid props like an inherited setter when you only provide `{value}`.
  * invalid props like an inherited setter when you only provide `{value}`.
  */
  */
 export const safeDefineProperty = (obj, key, desc) => (
 export const safeDefineProperty = (obj, key, desc) => (
-  defineProperty(obj, key, getPrototypeOf(desc) ? createNullObj(desc) : desc)
+  defineProperty(obj, key, getPrototypeOf(desc) ? nullObjFrom(desc) : desc)
 );
 );
 
 
 /** Unlike ::push() this one doesn't call possibly spoofed Array.prototype setters */
 /** Unlike ::push() this one doesn't call possibly spoofed Array.prototype setters */

+ 2 - 2
src/injected/web/gm-api-wrapper.js

@@ -32,7 +32,7 @@ export function makeGmApiWrapper(script) {
   const { meta } = script;
   const { meta } = script;
   const grant = meta.grant;
   const grant = meta.grant;
   const { id } = script.props;
   const { id } = script.props;
-  const resources = createNullObj(meta.resources);
+  const resources = nullObjFrom(meta.resources);
   /** @type {GMContext} */
   /** @type {GMContext} */
   const context = {
   const context = {
     __proto__: null, // necessary for optional props like `async`
     __proto__: null, // necessary for optional props like `async`
@@ -68,7 +68,7 @@ export function makeGmApiWrapper(script) {
     if (fnBound) {
     if (fnBound) {
       fn = safeBind(fn,
       fn = safeBind(fn,
         GM4_ASYNC[gm4name]
         GM4_ASYNC[gm4name]
-          ? contextAsync || (contextAsync = createNullObj({ async: true }, context))
+          ? contextAsync || (contextAsync = assign({ __proto__: null, async: true }, context))
           : context);
           : context);
     } else if (!fn && (
     } else if (!fn && (
       fn = name === 'window.close' && sendTabClose
       fn = name === 'window.close' && sendTabClose

+ 3 - 3
src/injected/web/gm-api.js

@@ -119,7 +119,7 @@ export const GM_API = {
       } else if (arg1) {
       } else if (arg1) {
         name = arg1.name;
         name = arg1.name;
         onload = arg1.onload;
         onload = arg1.onload;
-        pickIntoNullObj(opts, arg1, [
+        safePickInto(opts, arg1, [
           'url',
           'url',
           'headers',
           'headers',
           'timeout',
           'timeout',
@@ -142,7 +142,7 @@ export const GM_API = {
     },
     },
     /** @this {GMContext} */
     /** @this {GMContext} */
     GM_xmlhttpRequest(opts) {
     GM_xmlhttpRequest(opts) {
-      return onRequestCreate(createNullObj(opts), this);
+      return onRequestCreate(nullObjFrom(opts), this);
     },
     },
   },
   },
   free: {
   free: {
@@ -168,7 +168,7 @@ export const GM_API = {
       return webAddElement(null, 'style', { textContent: css, id: safeGetUniqId('VMst') });
       return webAddElement(null, 'style', { textContent: css, id: safeGetUniqId('VMst') });
     },
     },
     GM_openInTab(url, options) {
     GM_openInTab(url, options) {
-      options = createNullObj(isObject(options) ? options : { active: !options });
+      options = nullObjFrom(isObject(options) ? options : { active: !options });
       options.url = url;
       options.url = url;
       return onTabCreate(options);
       return onTabCreate(options);
     },
     },

+ 1 - 1
src/injected/web/gm-global-wrapper.js

@@ -48,7 +48,7 @@ const updateGlobalDesc = name => {
   if ((src = inheritedKeys[name])
   if ((src = inheritedKeys[name])
   || (src = globalKeysSet.get(name)) && (src = src > 0 ? window : global)) {
   || (src = globalKeysSet.get(name)) && (src = src > 0 ? window : global)) {
     if ((desc = describeProperty(src, name))) {
     if ((desc = describeProperty(src, name))) {
-      desc = createNullObj(desc);
+      desc = nullObjFrom(desc);
       if (typeof name === 'string' && name[0] > 'Z' && typeof desc.value === 'function') {
       if (typeof name === 'string' && name[0] > 'Z' && typeof desc.value === 'function') {
         desc.value = safeBind(desc.value, src === global ? global : window);
         desc.value = safeBind(desc.value, src === global ? global : window);
       }
       }

+ 1 - 1
src/injected/web/index.js

@@ -97,7 +97,7 @@ addHandlers({
 
 
 function createScriptData(item) {
 function createScriptData(item) {
   const { dataKey } = item;
   const { dataKey } = item;
-  store.values[item.props.id] = createNullObj(item.values);
+  store.values[item.props.id] = nullObjFrom(item.values);
   if (window[dataKey]) { // executeScript ran before GetInjected response
   if (window[dataKey]) { // executeScript ran before GetInjected response
     onCodeSet(item, window[dataKey]);
     onCodeSet(item, window[dataKey]);
   } else if (!item.meta.unwrap) {
   } else if (!item.meta.unwrap) {

+ 1 - 1
src/injected/web/requests.js

@@ -163,7 +163,7 @@ export function onRequestCreate(opts, context, fileName) {
     || IS_FIREFOX >= 56 && [data]
     || IS_FIREFOX >= 56 && [data]
     || [data, 'bin'];
     || [data, 'bin'];
   /** @type {GMReq.Message.Web} */
   /** @type {GMReq.Message.Web} */
-  bridge.call('HttpRequest', createNullObj({
+  bridge.call('HttpRequest', safePickInto({
     anonymous,
     anonymous,
     data,
     data,
     fileName,
     fileName,

+ 8 - 5
src/injected/web/safe-globals-web.js → src/injected/web/safe-globals.js

@@ -59,6 +59,7 @@ export let
   // various methods
   // various methods
   URLToString,
   URLToString,
   arrayIsArray,
   arrayIsArray,
+  createNullObj,
   createObjectURL,
   createObjectURL,
   formDataEntries,
   formDataEntries,
   hasOwnProperty,
   hasOwnProperty,
@@ -95,16 +96,17 @@ export const VAULT = (() => {
     res = window[VAULT_ID];
     res = window[VAULT_ID];
     delete window[VAULT_ID];
     delete window[VAULT_ID];
   }
   }
-  if (!res) {
-    res = createNullObj();
-  } else if (!isFunction(res[0])) {
+  if (res && !isFunction(res[0])) {
     // res is [this, addVaultExports object]
     // res is [this, addVaultExports object]
     // injectPageSandbox iframe's `global` is `window` because it's in page mode
     // injectPageSandbox iframe's `global` is `window` because it's in page mode
     src = res[0];
     src = res[0];
     srcWindow = src;
     srcWindow = src;
     // In FF some stuff from a detached iframe doesn't work, so we export it from content
     // In FF some stuff from a detached iframe doesn't work, so we export it from content
     srcFF = IS_FIREFOX && res[1];
     srcFF = IS_FIREFOX && res[1];
-    res = createNullObj();
+    res = false;
+  }
+  if (!res) {
+    res = { __proto__: null };
   }
   }
   res = [
   res = [
     // window
     // window
@@ -145,6 +147,7 @@ export const VAULT = (() => {
     safeBind = res[i += 1] || call.bind(SafeObject.bind),
     safeBind = res[i += 1] || call.bind(SafeObject.bind),
     // various methods
     // various methods
     URLToString = res[i += 1] || src.URL[PROTO].toString,
     URLToString = res[i += 1] || src.URL[PROTO].toString,
+    createNullObj = res[i += 1] || safeBind(SafeObject.create, SafeObject, null),
     createObjectURL = res[i += 1] || src.URL.createObjectURL,
     createObjectURL = res[i += 1] || src.URL.createObjectURL,
     formDataEntries = res[i += 1] || src.FormData[PROTO].entries,
     formDataEntries = res[i += 1] || src.FormData[PROTO].entries,
     hasOwnProperty = res[i += 1] || Reflect.has,
     hasOwnProperty = res[i += 1] || Reflect.has,
@@ -153,7 +156,7 @@ export const VAULT = (() => {
      * by the page if it gains access to any Object from the vault e.g. a thrown SafeError. */
      * by the page if it gains access to any Object from the vault e.g. a thrown SafeError. */
     jsonParse = res[i += 1] || src.JSON.parse,
     jsonParse = res[i += 1] || src.JSON.parse,
     jsonStringify = res[i += 1] || src.JSON.stringify,
     jsonStringify = res[i += 1] || src.JSON.stringify,
-    logging = res[i += 1] || createNullObj((srcFF || src).console),
+    logging = res[i += 1] || nullObjFrom((srcFF || src).console),
     mathRandom = res[i += 1] || src.Math.random,
     mathRandom = res[i += 1] || src.Math.random,
     parseFromString = res[i += 1] || SafeDOMParser[PROTO].parseFromString,
     parseFromString = res[i += 1] || SafeDOMParser[PROTO].parseFromString,
     reflectOwnKeys = res[i += 1] || Reflect.ownKeys,
     reflectOwnKeys = res[i += 1] || Reflect.ownKeys,

+ 1 - 1
src/injected/web/util.js

@@ -62,7 +62,7 @@ export const FastLookup = (hubs = createNullObj()) => {
       const clone = createNullObj();
       const clone = createNullObj();
       if (process.env.DEBUG) throwIfProtoPresent(clone);
       if (process.env.DEBUG) throwIfProtoPresent(clone);
       for (const group in hubs) { /* proto is null */// eslint-disable-line guard-for-in
       for (const group in hubs) { /* proto is null */// eslint-disable-line guard-for-in
-        clone[group] = createNullObj(hubs[group]);
+        clone[group] = nullObjFrom(hubs[group]);
       }
       }
       return FastLookup(clone);
       return FastLookup(clone);
     },
     },

+ 3 - 3
test/mock/polyfill.js

@@ -35,6 +35,6 @@ delete MessagePort.prototype.onmessage; // to avoid hanging
 global.PAGE_MODE_HANDSHAKE = 123;
 global.PAGE_MODE_HANDSHAKE = 123;
 global.VAULT_ID = false;
 global.VAULT_ID = false;
 Object.assign(global, require('@/common/safe-globals'));
 Object.assign(global, require('@/common/safe-globals'));
-Object.assign(global, require('@/injected/safe-globals-injected'));
-Object.assign(global, require('@/injected/content/safe-globals-content'));
-Object.assign(global, require('@/injected/web/safe-globals-web'));
+Object.assign(global, require('@/injected/safe-globals'));
+Object.assign(global, require('@/injected/content/safe-globals'));
+Object.assign(global, require('@/injected/web/safe-globals'));