You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -463,7 +465,7 @@ the container to exit explicitly, and we highly recommend setting
463
465
464
466
## `reporting` Options
465
467
466
-
**Background**: Lockdown and `repairIntrinsics` report warnings if they
468
+
**Background**: `lockdown` and `repairIntrinsics` report warnings if they
467
469
encounter unexpected but repairable variations on the shared intrinsics, which
468
470
regularly occurs if the version of `ses` predates the introduction of new
469
471
language features.
@@ -617,6 +619,70 @@ LOCKDOWN_EVAL_TAMING=noEval
617
619
LOCKDOWN_EVAL_TAMING=unsafeEval
618
620
```
619
621
622
+
## `hostEvaluators` Options
623
+
624
+
**Background**: Hermes is a JavaScript engine that does not yet support direct `eval()` nor the `with` statement. The SES `evalTaming` default option `"safeEval"` uses multiple nested `with` statements to create a restricted scope chain, so on Hermes we must run under the `"unsafeEval"` option. However SES cannot initialize unless 'eval' is the original intrinsic 'eval', suitable for direct-eval (dynamically scoped eval), which is where we introduce the `hostEvaluators` option `"no-direct"`.
625
+
626
+
```js
627
+
lockdown(); // Warning: `SES Please now use the 'hostEvaluators' option. In the future not specifying 'none' will error under strict CSP.`
628
+
// or
629
+
lockdown({ hostEvaluators:'all' }); // SES fails to initialize if direct-eval is not the original intrinsic 'eval'
630
+
// vs
631
+
lockdown({ hostEvaluators:'none' }); // SES initializes when evaluators are not allowed to execute (e.g. a strict CSP)
632
+
// vs
633
+
lockdown({ hostEvaluators:'no-direct' }); // SES initializes without direct-eval (e.g. on Hermes)
634
+
```
635
+
636
+
Further
637
+
638
+
*`'all'`: asserts evaluators are allowed to execute
639
+
*`'none'`: asserts evaluators are *not* allowed to execute
640
+
*`'no-direct'`: asserts direct-eval is not available
641
+
642
+
Hermes example
643
+
644
+
```js
645
+
lockdown({ evalTaming:'unsafeEval', hostEvaluators:'no-direct' }); // Recommended on Hermes
646
+
```
647
+
648
+
However, attempting `"safeEval"` with `"no-direct"` we fail early, due to Hermes' lack of `with` statement
649
+
650
+
```js
651
+
lockdown({ evalTaming:'safeEval', hostEvaluators:'no-direct' }); // Fail: `lockdown(): option evalTaming: safeEval is incompatible with hostEvaluators: no-direct`
652
+
```
653
+
654
+
Since Compartments currently evaluate using `safeEval` by default, we throw a descriptive error on attempt to `.evaluate`: `'Compartment evaluation not supported without direct eval.'` However this will only be surfaced once Compartment creation is supported on Hermes under `lockdown` (currently incompatible with `removeUnpermittedIntrinsics`).
655
+
656
+
For users with a strict CSP, `hostEvaluators` defaulting to `all` is a breaking change and will error (SES_DIRECT_EVAL), so for backward-compatibility we warn instead to set it to `none`.
657
+
658
+
If `lockdown` does not receive a `hostEvaluators` option, it will respect
659
+
`process.env.LOCKDOWN_HOST_EVALUATORS`.
660
+
661
+
```console
662
+
LOCKDOWN_HOST_EVALUATORS=all
663
+
LOCKDOWN_HOST_EVALUATORS=none
664
+
LOCKDOWN_HOST_EVALUATORS=no-direct
665
+
```
666
+
667
+
Once Hermes engine supports direct-eval, `'no-direct'` will no longer be required.
668
+
Currently there is an open feature request and open pull request targeting Static Hermes.
669
+
670
+
*<https://github.com/facebook/hermes/issues/957>
671
+
*<https://github.com/facebook/hermes/pull/1515>
672
+
673
+
You can also test and verify `lockdown` completing on this change by building and running Hermes on the following fork for example:
// This could be a strict Content Security Policy containing either a `default-src` or a `script-src` directive, or an ES host with broken APIs.
279
+
constnoEvaluators=!evalAllowed&&!functionAllowed;// eval() itself and the Function() constructor are not allowed to execute.
280
+
281
+
hostEvaluators==='all'&&
282
+
noEvaluators&&
283
+
Fail`'hostEvaluators' was set to 'all', but the Function() constructor and eval() are not allowed to execute (SES_DIRECT_EVAL)`;
284
+
285
+
hostEvaluators==='none'&&
286
+
!noEvaluators&&
287
+
Fail`'hostEvaluators' was set to 'none', but the Function() constructor and eval() are allowed to execute (SES_DIRECT_EVAL)`;
288
+
289
+
hostEvaluators==='no-direct'&&
290
+
directEvalAllowed&&
291
+
Fail`'hostEvaluators' was set to 'no-direct', but ${directEvalAllowed===true ? 'direct eval is functional' : 'the Function() constructor and eval() are not allowed to execute'} (SES_DIRECT_EVAL)`;
292
+
293
+
// TODO: Remove '_legacy' when 'all' introduced as the new default option (breaking change).
294
+
// For backwards compatibility under '_legacy', we do not error with a strict CSP, since directEvalAllowed remains undefined.
0 commit comments