diff --git a/packages/ses/src/commons.js b/packages/ses/src/commons.js index b4f8f6f391..d1b524dc6f 100644 --- a/packages/ses/src/commons.js +++ b/packages/ses/src/commons.js @@ -26,6 +26,7 @@ export const { JSON, Map, Math, + ModuleSource, Number, Object, Promise, diff --git a/packages/ses/src/lockdown.js b/packages/ses/src/lockdown.js index 170c341fbc..2c2ac13235 100644 --- a/packages/ses/src/lockdown.js +++ b/packages/ses/src/lockdown.js @@ -46,6 +46,7 @@ import { makeSafeEvaluator } from './make-safe-evaluator.js'; import { initialGlobalPropertyNames } from './permits.js'; import { tameFunctionToString } from './tame-function-tostring.js'; import { tameDomains } from './tame-domains.js'; +import { tameModuleSource } from './tame-module-source.js'; import { tameConsole } from './error/tame-console.js'; import tameErrorConstructor from './error/tame-error-constructor.js'; @@ -267,6 +268,8 @@ export const repairIntrinsics = (options = {}) => { tameDomains(domainTaming); + tameModuleSource(); + // Replace Function.prototype.toString with one that recognizes // shimmed functions as honorary native functions. const markVirtualizedNativeFunction = tameFunctionToString(); diff --git a/packages/ses/src/tame-module-source.js b/packages/ses/src/tame-module-source.js new file mode 100644 index 0000000000..0ce7cc06d8 --- /dev/null +++ b/packages/ses/src/tame-module-source.js @@ -0,0 +1,35 @@ +import { + ModuleSource, + functionPrototype, + getPrototypeOf, + objectPrototype, + setPrototypeOf, +} from './commons.js'; + +export const tameModuleSource = () => { + if (ModuleSource !== undefined) { + // We introduce ModuleSource.[[Proto]] === AbstractModuleSource + // and ModuleSource.prototype.[[Proto]] === AbstractModuleSource.prototype + // if that layer is absent because the permitting system can more + // gracefully tolerate the absence of an expected prototype than the + // presence of an unexpected prototype,. + function AbstractModuleSource() { + // no-op safe to super() + } + + const ModuleSourceProto = getPrototypeOf(ModuleSource); + if (ModuleSourceProto === functionPrototype) { + setPrototypeOf(ModuleSource, AbstractModuleSource); + } + + const ModuleSourcePrototype = ModuleSource.prototype; + if (ModuleSourcePrototype !== undefined) { + // ModuleSource.prototype.__proto__ should be the + // AbstractModuleSource.prototype. + const ModuleSourcePrototypeProto = getPrototypeOf(ModuleSourcePrototype); + if (ModuleSourcePrototypeProto === objectPrototype) { + setPrototypeOf(ModuleSource.prototype, AbstractModuleSource.prototype); + } + } + } +};