feat(ses): Check early for dynamic evalability
Fixes
MODIFY
packages/ses/src/lockdown-shim.js
packages/ses/src/lockdown-shim.js
// @ts-check
import {
+ FERAL_FUNCTION,
+ FERAL_EVAL,
TypeError,
arrayFilter,
arrayMap,
@@ -87,6 +89,27 @@ const harden = makeHardener();
// only ever need to be called once and that simplifying lockdown will improve
// the quality of audits.
+const directEvalUnavailable = () => {
+ throw new TypeError(
+ `SES cannot initialize unless 'eval' is the original intrinsic 'eval', suitable for direct-eval (dynamically scoped eval) (SES_DIRECT_EVAL)`,
+ );
+};
+
+const assertDirectEvalAvailable = () => {
+ try {
+ const changed = FERAL_FUNCTION(
+ 'eval',
+ 'changed',
+ 'eval("changed = true"); return changed',
+ )(FERAL_EVAL, false);
+ if (!changed) {
+ directEvalUnavailable();
+ }
+ } catch (error) {
+ directEvalUnavailable();
+ }
+};
+
/**
* @param {LockdownOptions} [options]
* @returns {() => void} repairIntrinsics
@@ -174,6 +197,8 @@ export const repairIntrinsics = (options = {}) => {
// trace retained:
priorLockdown.stack;
+ assertDirectEvalAvailable();
+
/**
* Because of packagers and bundlers, etc, multiple invocations of lockdown
* might happen in separate instantiations of the source of this module.

feat(ses): Check early for dynamic evalability

Fixes #343