Socket
Socket
Sign inDemoInstall

ses

Package Overview
Dependencies
Maintainers
6
Versions
103
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ses - npm Package Compare versions

Comparing version 0.18.4 to 0.18.5

src/permits-intrinsics.js

2

index.js

@@ -30,3 +30,3 @@ // Copyright (C) 2018 Agoric

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_NO_SLOPPY.md
throw new TypeError(`SES failed to initialize, sloppy mode (SES_NO_SLOPPY)`);
throw TypeError(`SES failed to initialize, sloppy mode (SES_NO_SLOPPY)`);
}

@@ -33,0 +33,0 @@

User-visible changes in SES:
# v0.18.5 (2023-07-14)
- Adds `assert.bare` for embedding unquoted strings in details.
- Permits new `dispose` symbols, other recent additions to JavaScript, and for
the anticipated iterator helpers.
- Tames `Symbol` so symbols can be preserved in the start compartment and
denied to shared compartments.
- Improves debugging in Safari.
- Adds missing native function markers.
All native functions should have a `toString` that says `[native code]`, even
if emulated.
# v0.18.4 (2023-04-20)

@@ -4,0 +16,0 @@

{
"name": "ses",
"version": "0.18.4",
"version": "0.18.5",
"description": "Hardened JavaScript for Fearless Cooperation",

@@ -62,19 +62,23 @@ "keywords": [

},
"dependencies": {
"@endo/env-options": "^0.1.1"
},
"devDependencies": {
"@endo/compartment-mapper": "^0.8.4",
"@endo/static-module-record": "^0.7.19",
"@endo/test262-runner": "^0.1.31",
"ava": "^5.2.0",
"@endo/compartment-mapper": "^0.8.5",
"@endo/static-module-record": "^0.7.20",
"@endo/test262-runner": "^0.1.32",
"ava": "^5.3.0",
"babel-eslint": "^10.0.3",
"c8": "^7.7.3",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.0.0",
"c8": "^7.14.0",
"core-js": "^3.31.0",
"eslint": "^8.44.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-eslint-comments": "^3.1.2",
"eslint-plugin-import": "^2.27.5",
"prettier": "^2.8.5",
"sinon": "8.0.4",
"prettier": "^3.0.0",
"sinon": "^15.1.0",
"terser": "^5.16.6",
"tsd": "^0.24.1",
"typescript": "~4.9.5"
"tsd": "^0.28.1",
"typescript": "~5.1.3"
},

@@ -179,3 +183,3 @@ "files": [

},
"gitHead": "38c2c59d6ae8c53f84cd333e6c7828e2d37604e2"
"gitHead": "106da55b8bcea3067f70c29c357806f3f2e55c52"
}

@@ -5,3 +5,3 @@ # SES

This package is a SES [shim][define shim] for JavaScript features
[proposed][SES proposal] to ECMA TC-39.
[proposed][SES proposal] to ECMA TC39.
Hardened JavaScript is highly compatible with ordinary JavaScript.

@@ -74,3 +74,4 @@ Most existing JavaScript libraries can run on hardened JavaScript.

**realm**, such that no two programs running in the same realm can observe or
interfere with each other until they have been introduced.
affect each other until they have been introduced, and even then can only
interact through their own exposed interfaces.

@@ -85,6 +86,6 @@ To do this, `lockdown()` tamper-proofs all of the JavaScript intrinsics, to

Lockdown freezes all objects accessible to any program in the realm.
The set of accessible objects includes but is not limited to: `globalThis`,
`[].__proto__`, `{}.__proto__`, `(() => {}).__proto__` `(async () =>
{}).__proto__`, and the properties of any accessible object.
Lockdown freezes all objects that are effectively undeniable to programs in the
realm. The set of such objects includes but is not limited to: `globalThis`,
prototype objects of Array, Function, GeneratorFunction, and Object, and objects
accessible from those objects (such as `Object.prototype.toString`).

@@ -97,3 +98,3 @@ The `lockdown()` function also **tames** some objects including regular

Lockdown replaces locale methods like `String.prototype.localeCompare` with
lexical versions that do not reveal the user locale.
generic versions that do not reveal the host locale.

@@ -147,4 +148,4 @@ ```js

still closes over the mutable counter.
Hardening an object graph makes the surface immutable, but does not make
methods pure.
Hardening an object graph makes the surface immutable, but does not guarantee
that methods are free of side effects.

@@ -530,3 +531,3 @@

taming hides error stacks, accumulating them in side tables. The `assert`
system generated other diagnostic information hidden in side tables. The tamed
system generates other diagnostic information hidden in side tables. The tamed
console uses these side tables to output more informative diagnostics.

@@ -551,6 +552,9 @@ [Logging Errors](./src/error/README.md) explains the design.

Provided that the `ses` implementation and its trusted compute base are
correct, we claim that a host program (Figure 1) can evaluate a guest program
(`program`) in a compartment after `lockdown` and that the program:
### Single-guest Compartment Isolation
Provided that the `ses` implementation and its
[trusted compute base](#trusted-compute-base) are correct, we claim that a host
program can evaluate a guest program (`program`) in a compartment after
`lockdown` and that the guest program:
- will initially only have access to one mutable object, the compartment's

@@ -577,3 +581,2 @@ `globalThis`,

```js
// Claims, Figure 1
lockdown();

@@ -584,5 +587,8 @@ const compartment = new Compartment();

If the host program (Figure 2) arranges for the compartment's `globalThis` to
### Multi-guest Compartment Isolation
If the host program arranges for the compartment's `globalThis` to
be frozen, we additionally claim that the host can evaluate any two guest
programs (`program1` and `program2`) such that neither program will:
programs (`program1` and `program2`) in that compartment such that neither
guest program will:

@@ -597,3 +603,2 @@ - initially share *any* mutable objects.

```js
// Claims, Figure 2
lockdown();

@@ -606,27 +611,26 @@ const compartment = new Compartment();

However such programs (`program`, `program1`, or `program2`) are only
as useful as a calculator.
A host program is therefore responsible for maintaining any of the desired
invariants above when "endowing" a compartment with any of its own objects.
### Endowment Protection
For example, a host program (Figure 3) may run two programs in separate
compartments, giving one program the ability to resolve a promise and the other
program the ability to observe the settlement (fulfillment or rejection) of
The above `program`, `program1`, and `program2` guest programs are only useful
as glorified calculators.
When going beyond that by "endowing" a compartment with extra objects, a host
program is responsible for maintaining any of the invariants above that it
considers necessary.
For example, a host program may run two guest programs in separate
compartments, giving one the ability to resolve a promise and the other
the ability to observe the settlement (fulfillment or rejection) of
that promise.
The host program is responsible for hardening these objects.
The host program is responsible for hardening the objects implementing such
abilities.
```js
// Claims, Figure 2
lockdown();
const promise = new Promise(resolve => {
const compartmentA = new Compartment(harden({
resolve,
}));
compartment.evaluate(programA);
const compartmentA = new Compartment(harden({ resolve }));
compartmentA.evaluate(programA);
});
const compartmentB = new Compartment(harden({
promise,
}));
const compartmentB = new Compartment(harden({ promise }));
compartmentB.evaluate(programB);

@@ -639,9 +643,10 @@ ```

### Caveats
Host programs must maintain the `ses` boundary with care in what they present
as endowments.
A host program should take care not to share mutable state with guests,
or distribute mutable state to multiple guests, such as an unfrozen object (use
`harden`), direct read and write access to a collection, like a `Map` or `Set`,
even if hardened.
Furthermore, typed arrays are collections and cannot be hardened.
or distribute mutable state to multiple guests, such as an object that has not
been frozen with `harden` or a collection like a `Map` or `Set` or typed array
(collections retain some mutability even if hardened).

@@ -662,4 +667,3 @@ For the purposes of sharing state, pseudo-random number generators (PRNG) like

when evaluated in separate compartments.
This is relevant when program created objects are shared between guest
programs.
This is relevant when objects are shared between guest programs.

@@ -672,4 +676,4 @@ When a program interacts with an object introduced by another program (as

another program, like property accessors or proxy traps, to execute on the same
stack, which may be able to call back into the program (reentrancy), throw, or
detect the current stack height.
stack, which may be able to detect the stack height, throw an exception, or call
back into the program in pursuit of a reentrancy attack.

@@ -683,2 +687,4 @@ A host object can defend itself from reentrancy attacks by ensuring that it

### Trusted Compute Base
The trusted compute base (TCB) for `ses` includes:

@@ -715,6 +721,5 @@

No critical flaws in the code surfaced during the review.
As a result of the search for flaws, deficiencies, and weaknesses in the code
(which is currently a Stage 1 proposal with the ECMA TC39 committee), a series
of small code changes and documentation improvements were made. There is a
report available on the
As a result of the search for flaws, deficiencies, and weaknesses in the code,
a series of small code changes and documentation improvements were made. There
is a report available on the
[Agoric blog](https://agoric.com/blog/technology/purple-teaming-how-metamask-and-agoric-hunted-bugs-to-harden-javascript)

@@ -745,9 +750,62 @@ that includes links to recordings of code walk-throughs and technical

## Ecosystem Compatibility
Most ordinary JavaScript can run without issues in a realm locked down by SES.
Exceptions are tracked at [issue #576][incompatibility tracking], and almost
always take the form of assignments that fail because the
"[override mistake][override mistake]" prevents overriding properties inherited
from a frozen intrinsic object in the prototype chain. When that is the case,
the code is often incompatible with *all* environments in which intrinsic
objects are frozen (such as in Node.js with the
[`--frozen-intrinsics`][Node frozen intrinsics] option) and can be fixed by
replacing `<lhs>.<propertyKey> = <rhs>;` or `<lhs>[<propertyKey>] = <rhs>;` with
```js
Object.defineProperties(<lhs>, {
[<propertyKey>]: {
value: <rhs>,
writable: true,
enumerable: true,
configurable: true,
},
});
```
Upon encountering an incompatibility, we recommend that you add a comment to
[issue #576][incompatibility tracking] and file an issue with the external
project referencing this section.
Projects often have their own unique issue reporting templates, but generally
provide some place to include text like
> ```
> This project has some assignments that break in an environment with frozen
> intrinsic objects, such as
> [Hardened JS (a.k.a. SES)](https://github.com/endojs/endo/blob/master/packages/ses#ecosystem-compatibility)
> or Node.js with the
> [`--frozen-intrinsics`](https://nodejs.org/docs/latest/api/cli.html#--frozen-intrinsics)
> option.
> Specifically, [link to source in the project] does not work correctly in such
> an environment.
>
> Please consider increasing support by replacing assignments to object
> properties inherited from intrinsics with use of `Object.defineProperties`
> (thereby working around the JavaScript "override mistake"), and if applicable
> also by avoiding mutation of intrinsic objects.
> If you don't have the capacity but would accept a PR, please comment to that
> effect so that a volunteer knows their efforts would be welcomed.
> ```
We find that library authors are generally amenable to making these small changes to increase
compatibility with any environment that protects itself from prototype pollution attacks by freezing
intrinsics, including `ses`.
[define shim]: https://en.wikipedia.org/wiki/Shim_(computing)
[SES proposal]: https://github.com/tc39/proposal-ses
[Endo Matrix]: https://matrix.to/#/#endojs:matrix.org
[incompatibility tracking]: https://github.com/endojs/endo/issues/576
[Node frozen intrinsics]: https://nodejs.org/docs/latest/api/cli.html#--frozen-intrinsics
[override mistake]: https://web.archive.org/web/20141230041441/http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake
[SECURITY.md]: https://github.com/endojs/endo/blob/master/packages/ses/SECURITY.md
[SES Issues]: https://github.com/endojs/endo/issues
[SES proposal]: https://github.com/tc39/proposal-ses
[SES Strategy Group]: https://groups.google.com/g/ses-strategy
[SES Strategy Recordings]: https://www.youtube.com/playlist?list=PLzDw4TTug5O1jzKodRDp3qec8zl88oxGd
[Endo Matrix]: https://matrix.to/#/#endojs:matrix.org

@@ -36,2 +36,3 @@ /* global globalThis */

String,
Symbol,
WeakMap,

@@ -291,5 +292,3 @@ WeakSet,

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_NO_EVAL.md
throw new TypeError(
'Cannot eval with evalTaming set to "noEval" (SES_NO_EVAL)',
);
throw TypeError('Cannot eval with evalTaming set to "noEval" (SES_NO_EVAL)');
};

@@ -64,3 +64,3 @@ /// <reference types="ses">

if (typeof source !== 'string') {
throw new TypeError('first argument of evaluate() must be a string');
throw TypeError('first argument of evaluate() must be a string');
}

@@ -67,0 +67,0 @@

@@ -23,3 +23,3 @@ // @ts-check

} from './global-object.js';
import { sharedGlobalPropertyNames } from './whitelist.js';
import { sharedGlobalPropertyNames } from './permits.js';
import { load } from './module-load.js';

@@ -52,3 +52,3 @@ import { link } from './module-link.js';

if (typeof importHook !== 'function' || typeof resolveHook !== 'function') {
throw new TypeError(
throw TypeError(
'Compartment must be constructed with an importHook and a resolveHook for it to be able to load modules',

@@ -64,3 +64,3 @@ );

) {
throw new TypeError(
throw TypeError(
'Compartment.prototype.constructor is not a valid constructor.',

@@ -117,3 +117,3 @@ );

if (typeof specifier !== 'string') {
throw new TypeError('first argument of module() must be a string');
throw TypeError('first argument of module() must be a string');
}

@@ -135,3 +135,3 @@

if (typeof specifier !== 'string') {
throw new TypeError('first argument of import() must be a string');
throw TypeError('first argument of import() must be a string');
}

@@ -157,3 +157,3 @@

if (typeof specifier !== 'string') {
throw new TypeError('first argument of load() must be a string');
throw TypeError('first argument of load() must be a string');
}

@@ -168,3 +168,3 @@

if (typeof specifier !== 'string') {
throw new TypeError('first argument of importNow() must be a string');
throw TypeError('first argument of importNow() must be a string');
}

@@ -198,3 +198,3 @@

if (new.target === undefined) {
throw new TypeError(
throw TypeError(
"Class constructor Compartment cannot be invoked without 'new'",

@@ -231,3 +231,3 @@ );

// TODO implement parent module record retrieval.
throw new TypeError(
throw TypeError(
`Cannot map module ${q(specifier)} to ${q(

@@ -234,0 +234,0 @@ aliasNamespace,

@@ -105,3 +105,3 @@ // Adapted from SES/Caja

if (obj === this) {
throw new TypeError(
throw TypeError(
`Cannot assign to read only property '${String(

@@ -117,3 +117,3 @@ prop,

// eslint-disable-next-line @endo/no-polymorphic-call
console.error(new TypeError(`Override property ${prop}`));
console.error(TypeError(`Override property ${prop}`));
}

@@ -180,3 +180,3 @@ defineProperty(this, prop, {

} else {
throw new TypeError(`Unexpected override enablement plan ${subPath}`);
throw TypeError(`Unexpected override enablement plan ${subPath}`);
}

@@ -201,3 +201,3 @@ }

default: {
throw new TypeError(`unrecognized overrideTaming ${overrideTaming}`);
throw TypeError(`unrecognized overrideTaming ${overrideTaming}`);
}

@@ -204,0 +204,0 @@ }

@@ -27,2 +27,3 @@ // Copyright (C) 2019 Agoric, under Apache License 2.0

isError,
regexpTest,
stringIndexOf,

@@ -60,2 +61,31 @@ stringReplace,

const canBeBare = freeze(/^[\w:-]( ?[\w:-])*$/);
/**
* Embed a string directly into error details without wrapping punctuation.
* To avoid injection attacks that exploit quoting confusion, this must NEVER
* be used with data that is possibly attacker-controlled.
* As a further safeguard, we fall back to quoting any input that is not a
* string of sufficiently word-like parts separated by isolated spaces (rather
* than throwing an exception, which could hide the original problem for which
* explanatory details are being constructed---i.e., ``` assert.details`...` ```
* should never be the source of a new exception, nor should an attempt to
* render its output, although we _could_ instead decide to handle the latter
* by inline replacement similar to that of `bestEffortStringify` for producing
* rendered messages like `(an object) was tagged "[Unsafe bare string]"`).
*
* @type {AssertQuote}
*/
const bare = (payload, spaces = undefined) => {
if (typeof payload !== 'string' || !regexpTest(canBeBare, payload)) {
return quote(payload, spaces);
}
const result = freeze({
toString: freeze(() => payload),
});
weakmapSet(declassifiers, result, payload);
return result;
};
freeze(bare);
// /////////////////////////////////////////////////////////////////////////////

@@ -242,3 +272,3 @@

if (hiddenDetails === undefined) {
throw new TypeError(`unrecognized details ${quote(optDetails)}`);
throw TypeError(`unrecognized details ${quote(optDetails)}`);
}

@@ -283,3 +313,3 @@ const messageString = getMessageString(hiddenDetails);

if (hiddenDetails === undefined) {
throw new TypeError(`unrecognized details ${quote(detailsNote)}`);
throw TypeError(`unrecognized details ${quote(detailsNote)}`);
}

@@ -410,9 +440,5 @@ const logArgs = getLogArgs(hiddenDetails);

if (optDetails === undefined) {
// Like
// ```js
// optDetails = details`${specimen} must be ${quote(an(typename))}`;
// ```
// except it puts the typename into the literal part of the template
// so it doesn't get quoted.
optDetails = details(['', ` must be ${an(typename)}`], specimen);
// Embed the type phrase without quotes.
const typeWithDeterminer = an(typename);
optDetails = details`${specimen} must be ${bare(typeWithDeterminer)}`;
}

@@ -439,2 +465,3 @@ fail(optDetails, TypeError);

quote,
bare,
makeAssert,

@@ -441,0 +468,0 @@ });

@@ -105,5 +105,3 @@ // @ts-check

if (!isSafeInteger(keysBudget) || keysBudget < 0) {
throw new TypeError(
'keysBudget must be a safe non-negative integer number',
);
throw TypeError('keysBudget must be a safe non-negative integer number');
}

@@ -231,3 +229,3 @@ /** @typedef {DoublyLinkedCell<WeakMap<K, V> | undefined>} LRUCacheCell */

if (!isSafeInteger(argsPerErrorBudget) || argsPerErrorBudget < 1) {
throw new TypeError(
throw TypeError(
'argsPerErrorBudget must be a safe positive integer number',

@@ -234,0 +232,0 @@ );

@@ -31,3 +31,3 @@ // @ts-check

if (consoleTaming !== 'safe' && consoleTaming !== 'unsafe') {
throw new TypeError(`unrecognized consoleTaming ${consoleTaming}`);
throw TypeError(`unrecognized consoleTaming ${consoleTaming}`);
}

@@ -34,0 +34,0 @@

@@ -11,3 +11,3 @@ import {

} from '../commons.js';
import { NativeErrors } from '../whitelist.js';
import { NativeErrors } from '../permits.js';
import { tameV8ErrorConstructor } from './tame-v8-error-constructor.js';

@@ -39,6 +39,6 @@

if (errorTaming !== 'safe' && errorTaming !== 'unsafe') {
throw new TypeError(`unrecognized errorTaming ${errorTaming}`);
throw TypeError(`unrecognized errorTaming ${errorTaming}`);
}
if (stackFiltering !== 'concise' && stackFiltering !== 'verbose') {
throw new TypeError(`unrecognized stackFiltering ${stackFiltering}`);
throw TypeError(`unrecognized stackFiltering ${stackFiltering}`);
}

@@ -45,0 +45,0 @@ const ErrorPrototype = FERAL_ERROR.prototype;

@@ -344,2 +344,3 @@ // @ts-check

* quote: AssertQuote,
* bare: AssertQuote,
* makeAssert: MakeAssert,

@@ -346,0 +347,0 @@ * } } Assert

@@ -16,2 +16,3 @@ import {

regexpPrototype,
globalThis,
} from './commons.js';

@@ -138,3 +139,25 @@ import { InertCompartment } from './compartment-shim.js';

if (globalThis.Iterator) {
intrinsics['%IteratorHelperPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.Iterator.from([]).take(0),
);
intrinsics['%WrapForValidIteratorPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.Iterator.from({ next() {} }),
);
}
if (globalThis.AsyncIterator) {
intrinsics['%AsyncIteratorHelperPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from([]).take(0),
);
intrinsics['%WrapForValidAsyncIteratorPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from({ next() {} }),
);
}
return intrinsics;
};

@@ -13,3 +13,3 @@ import {

import { makeFunctionConstructor } from './make-function-constructor.js';
import { constantProperties, universalPropertyNames } from './whitelist.js';
import { constantProperties, universalPropertyNames } from './permits.js';

@@ -35,3 +35,3 @@ /**

set: freeze(() => {
throw new TypeError(
throw TypeError(
`Cannot set Symbol.unscopables of a Compartment's globalThis`,

@@ -38,0 +38,0 @@ );

@@ -23,4 +23,4 @@ import {

universalPropertyNames,
whitelist,
} from './whitelist.js';
permitted,
} from './permits.js';

@@ -47,3 +47,3 @@ const isFunction = obj => typeof obj === 'function';

) {
throw new TypeError(`Conflicting definitions of ${name}`);
throw TypeError(`Conflicting definitions of ${name}`);
}

@@ -99,15 +99,15 @@ }

}
const permit = whitelist[name];
const permit = permitted[name];
if (typeof permit !== 'object') {
throw new TypeError(`Expected permit object at whitelist.${name}`);
throw TypeError(`Expected permit object at whitelist.${name}`);
}
const namePrototype = permit.prototype;
if (!namePrototype) {
throw new TypeError(`${name}.prototype property not whitelisted`);
throw TypeError(`${name}.prototype property not whitelisted`);
}
if (
typeof namePrototype !== 'string' ||
!objectHasOwnProperty(whitelist, namePrototype)
!objectHasOwnProperty(permitted, namePrototype)
) {
throw new TypeError(`Unrecognized ${name}.prototype whitelist entry`);
throw TypeError(`Unrecognized ${name}.prototype whitelist entry`);
}

@@ -117,3 +117,3 @@ const intrinsicPrototype = intrinsic.prototype;

if (intrinsics[namePrototype] !== intrinsicPrototype) {
throw new TypeError(`Conflicting bindings of ${namePrototype}`);
throw TypeError(`Conflicting bindings of ${namePrototype}`);
}

@@ -137,3 +137,3 @@ // eslint-disable-next-line no-continue

if (!pseudoNatives) {
throw new TypeError(
throw TypeError(
'isPseudoNative can only be called after finalIntrinsics',

@@ -140,0 +140,0 @@ );

@@ -17,2 +17,3 @@ // Copyright (C) 2018 Agoric

import { makeEnvironmentCaptor } from '@endo/env-options';
import {

@@ -23,3 +24,2 @@ FERAL_FUNCTION,

arrayFilter,
arrayMap,
globalThis,

@@ -31,6 +31,5 @@ is,

} from './commons.js';
import { enJoin } from './error/stringify-utils.js';
import { makeHardener } from './make-hardener.js';
import { makeIntrinsicsCollector } from './intrinsics.js';
import whitelistIntrinsics from './whitelist-intrinsics.js';
import whitelistIntrinsics from './permits-intrinsics.js';
import tameFunctionConstructors from './tame-function-constructors.js';

@@ -48,3 +47,3 @@ import tameDateConstructor from './tame-date-constructor.js';

import { makeSafeEvaluator } from './make-safe-evaluator.js';
import { initialGlobalPropertyNames } from './whitelist.js';
import { initialGlobalPropertyNames } from './permits.js';
import { tameFunctionToString } from './tame-function-tostring.js';

@@ -56,6 +55,6 @@ import { tameDomains } from './tame-domains.js';

import { assert, makeAssert } from './error/assert.js';
import { makeEnvironmentCaptor } from './environment-options.js';
import { getAnonymousIntrinsics } from './get-anonymous-intrinsics.js';
import { makeCompartmentConstructor } from './compartment-shim.js';
import { tameHarden } from './tame-harden.js';
import { tameSymbolConstructor } from './tame-symbol-constructor.js';

@@ -125,3 +124,3 @@ /** @typedef {import('../types.js').LockdownOptions} LockdownOptions */

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_DIRECT_EVAL.md
throw new TypeError(
throw TypeError(
`SES cannot initialize unless 'eval' is the original intrinsic 'eval', suitable for direct-eval (dynamically scoped eval) (SES_DIRECT_EVAL)`,

@@ -162,4 +161,3 @@ );

const { getEnvironmentOption: getenv, getCapturedEnvironmentOptionNames } =
makeEnvironmentCaptor(globalThis);
const { getEnvironmentOption: getenv } = makeEnvironmentCaptor(globalThis);

@@ -191,13 +189,2 @@ const {

const capturedEnvironmentOptionNames = getCapturedEnvironmentOptionNames();
if (capturedEnvironmentOptionNames.length > 0) {
// eslint-disable-next-line @endo/no-polymorphic-call
console.warn(
`SES Lockdown using options from environment variables ${enJoin(
arrayMap(capturedEnvironmentOptionNames, q),
'and',
)}`,
);
}
evalTaming === 'unsafeEval' ||

@@ -221,3 +208,3 @@ evalTaming === 'safeEval' ||

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_ALREADY_LOCKED_DOWN.md
priorLockdown = new TypeError('Prior lockdown (SES_ALREADY_LOCKED_DOWN)');
priorLockdown = TypeError('Prior lockdown (SES_ALREADY_LOCKED_DOWN)');
// Tease V8 to generate the stack string and release the closures the stack

@@ -264,3 +251,3 @@ // trace retained:

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_MULTIPLE_INSTANCES.md
throw new TypeError(
throw TypeError(
`Already locked down but not by this SES instance (SES_MULTIPLE_INSTANCES)`,

@@ -276,2 +263,6 @@ );

// Replace Function.prototype.toString with one that recognizes
// shimmed functions as honorary native functions.
const markVirtualizedNativeFunction = tameFunctionToString();
const { addIntrinsics, completePrototypes, finalIntrinsics } =

@@ -289,2 +280,3 @@ makeIntrinsicsCollector();

addIntrinsics(tameRegExpConstructor(regExpTaming));
addIntrinsics(tameSymbolConstructor());

@@ -310,3 +302,2 @@ addIntrinsics(getAnonymousIntrinsics());

const consoleRecord = tameConsole(
// @ts-expect-error tameConsole does its own input validation
consoleTaming,

@@ -333,6 +324,2 @@ errorTrapping,

// Replace Function.prototype.toString with one that recognizes
// shimmed functions as honorary native functions.
const markVirtualizedNativeFunction = tameFunctionToString();
/**

@@ -339,0 +326,0 @@ * 2. WHITELIST to standardize the environment.

@@ -163,3 +163,3 @@ // Adapted from SES/Caja - Copyright (C) 2011 Google Inc.

// future proof: break until someone figures out what it should do
throw new TypeError(`Unexpected typeof: ${type}`);
throw TypeError(`Unexpected typeof: ${type}`);
}

@@ -166,0 +166,0 @@ if (weaksetHas(hardened, val) || setHas(toFreeze, val)) {

@@ -49,3 +49,3 @@ import { assert } from './error/assert.js';

) {
throw new TypeError(
throw TypeError(
`SES third-party static module record "exports" property must be an array of strings for module ${moduleSpecifier}`,

@@ -199,5 +199,3 @@ );

if (tdz) {
throw new ReferenceError(
`binding ${q(localName)} not yet initialized`,
);
throw ReferenceError(`binding ${q(localName)} not yet initialized`);
}

@@ -212,3 +210,3 @@ return value;

if (!tdz) {
throw new TypeError(
throw TypeError(
`Internal: binding ${q(localName)} already initialized`,

@@ -273,3 +271,3 @@ );

if (tdz) {
throw new ReferenceError(
throw ReferenceError(
`binding ${q(liveExportName)} not yet initialized`,

@@ -301,5 +299,3 @@ );

if (tdz) {
throw new ReferenceError(
`binding ${q(localName)} not yet initialized`,
);
throw ReferenceError(`binding ${q(localName)} not yet initialized`);
}

@@ -306,0 +302,0 @@ value = newValue;

@@ -50,3 +50,3 @@ /* eslint-disable no-underscore-dangle */

if (moduleRecord === undefined) {
throw new ReferenceError(
throw ReferenceError(
`Missing link to module ${q(moduleSpecifier)} from compartment ${q(

@@ -156,3 +156,3 @@ compartmentName,

} else {
throw new TypeError(
throw TypeError(
`importHook must return a static module record, got ${q(

@@ -159,0 +159,0 @@ staticModuleRecord,

@@ -184,3 +184,3 @@ // For brevity, in this file, as in module-link.js, the term "moduleRecord"

if (staticModuleRecord.compartment !== undefined) {
throw new TypeError(
throw TypeError(
'Cannot redirect to an explicit record with a specified compartment',

@@ -215,3 +215,3 @@ );

if (staticModuleRecord.importMeta !== undefined) {
throw new TypeError(
throw TypeError(
'Cannot redirect to an implicit record with a specified importMeta',

@@ -235,5 +235,3 @@ );

throw new TypeError(
'Unnexpected RedirectStaticModuleInterface record shape',
);
throw TypeError('Unnexpected RedirectStaticModuleInterface record shape');
}

@@ -357,3 +355,3 @@

if (errors.length > 0) {
throw new TypeError(
throw TypeError(
`Failed to load module ${q(moduleSpecifier)} in package ${q(

@@ -360,0 +358,0 @@ compartmentName,

@@ -63,3 +63,3 @@ // Compartments need a mechanism to link a module from one compartment

if (!active) {
throw new TypeError(
throw TypeError(
`Cannot get property ${q(

@@ -73,3 +73,3 @@ name,

set(_target, name, _value) {
throw new TypeError(
throw TypeError(
`Cannot set property ${q(name)} of module exports namespace`,

@@ -80,3 +80,3 @@ );

if (!active) {
throw new TypeError(
throw TypeError(
`Cannot check property ${q(

@@ -90,3 +90,3 @@ name,

deleteProperty(_target, name) {
throw new TypeError(
throw TypeError(
`Cannot delete property ${q(name)}s of module exports namespace`,

@@ -97,3 +97,3 @@ );

if (!active) {
throw new TypeError(
throw TypeError(
'Cannot enumerate keys, the module has not yet begun to execute',

@@ -106,3 +106,3 @@ );

if (!active) {
throw new TypeError(
throw TypeError(
`Cannot get own property descriptor ${q(

@@ -117,3 +117,3 @@ name,

if (!active) {
throw new TypeError(
throw TypeError(
'Cannot prevent extensions of module exports namespace, the module has not yet begun to execute',

@@ -126,3 +126,3 @@ );

if (!active) {
throw new TypeError(
throw TypeError(
'Cannot check extensibility of module exports namespace, the module has not yet begun to execute',

@@ -137,6 +137,6 @@ );

setPrototypeOf(_target, _proto) {
throw new TypeError('Cannot set prototype of module exports namespace');
throw TypeError('Cannot set prototype of module exports namespace');
},
defineProperty(_target, name, _descriptor) {
throw new TypeError(
throw TypeError(
`Cannot define property ${q(name)} of module exports namespace`,

@@ -146,3 +146,3 @@ );

apply(_target, _thisArg, _args) {
throw new TypeError(
throw TypeError(
'Cannot call module exports namespace, it is not a function',

@@ -152,3 +152,3 @@ );

construct(_target, _args) {
throw new TypeError(
throw TypeError(
'Cannot construct module exports namespace, it is not a constructor',

@@ -155,0 +155,0 @@ );

@@ -46,3 +46,3 @@ import {

// ReferenceError message "Uncaught ReferenceError: xyz is not defined"
throw new ReferenceError(`${String(prop)} is not defined`);
throw ReferenceError(`${String(prop)} is not defined`);
},

@@ -57,3 +57,3 @@

// https://bugs.webkit.org/show_bug.cgi?id=195534
getPrototypeOf() {
getPrototypeOf(_shadow) {
return null;

@@ -64,3 +64,3 @@ },

// TODO: report as bug to v8 or Chrome, and record issue link here.
getOwnPropertyDescriptor(_target, prop) {
getOwnPropertyDescriptor(_shadow, prop) {
// Coerce with `String` in case prop is a symbol.

@@ -71,6 +71,12 @@ const quotedProp = q(String(prop));

`getOwnPropertyDescriptor trap on scopeTerminatorHandler for ${quotedProp}`,
new TypeError().stack,
TypeError().stack,
);
return undefined;
},
// See https://github.com/endojs/endo/issues/1490
// TODO Report bug to JSC or Safari
ownKeys(_shadow) {
return [];
},
};

@@ -77,0 +83,0 @@

@@ -13,3 +13,3 @@ // @ts-check

if (dateTaming !== 'safe' && dateTaming !== 'unsafe') {
throw new TypeError(`unrecognized dateTaming ${dateTaming}`);
throw TypeError(`unrecognized dateTaming ${dateTaming}`);
}

@@ -16,0 +16,0 @@ const OriginalDate = Date;

@@ -12,3 +12,3 @@ // @ts-check

if (domainTaming !== 'safe' && domainTaming !== 'unsafe') {
throw new TypeError(`unrecognized domainTaming ${domainTaming}`);
throw TypeError(`unrecognized domainTaming ${domainTaming}`);
}

@@ -31,3 +31,3 @@

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_NO_DOMAINS.md
throw new TypeError(
throw TypeError(
`SES failed to lockdown, Node.js domains have been initialized (SES_NO_DOMAINS)`,

@@ -34,0 +34,0 @@ );

@@ -33,3 +33,3 @@ import {

// In addition, the standard needs to define four new intrinsics for the safe
// replacement functions. See [./whitelist intrinsics].
// replacement functions. See [./permits-intrinsics.js].
//

@@ -88,3 +88,3 @@ // Adapted from SES/Caja

const InertConstructor = function () {
throw new TypeError(
throw TypeError(
'Function.prototype.constructor is not a valid constructor.',

@@ -91,0 +91,0 @@ );

@@ -6,3 +6,3 @@ /* eslint-disable no-restricted-globals */

if (hardenTaming !== 'safe' && hardenTaming !== 'unsafe') {
throw new TypeError(`unrecognized fakeHardenOption ${hardenTaming}`);
throw TypeError(`unrecognized fakeHardenOption ${hardenTaming}`);
}

@@ -9,0 +9,0 @@

@@ -22,3 +22,3 @@ import {

if (this === null || this === undefined) {
throw new TypeError(
throw TypeError(
'Cannot localeCompare with null or undefined "this" value',

@@ -49,3 +49,3 @@ );

if (localeTaming !== 'safe' && localeTaming !== 'unsafe') {
throw new TypeError(`unrecognized localeTaming ${localeTaming}`);
throw TypeError(`unrecognized localeTaming ${localeTaming}`);
}

@@ -52,0 +52,0 @@ if (localeTaming === 'unsafe') {

@@ -11,3 +11,3 @@ import {

if (mathTaming !== 'safe' && mathTaming !== 'unsafe') {
throw new TypeError(`unrecognized mathTaming ${mathTaming}`);
throw TypeError(`unrecognized mathTaming ${mathTaming}`);
}

@@ -14,0 +14,0 @@ const originalMath = Math;

@@ -12,3 +12,3 @@ import {

if (regExpTaming !== 'safe' && regExpTaming !== 'unsafe') {
throw new TypeError(`unrecognized regExpTaming ${regExpTaming}`);
throw TypeError(`unrecognized regExpTaming ${regExpTaming}`);
}

@@ -31,3 +31,3 @@ const RegExpPrototype = FERAL_REG_EXP.prototype;

if (!speciesDesc) {
throw new TypeError('no RegExp[Symbol.species] descriptor');
throw TypeError('no RegExp[Symbol.species] descriptor');
}

@@ -34,0 +34,0 @@

@@ -74,3 +74,3 @@ // @ts-check

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_HTML_COMMENT_REJECTED.md
throw new SyntaxError(
throw SyntaxError(
`Possible HTML comment rejected at ${name}:${lineNumber}. (SES_HTML_COMMENT_REJECTED)`,

@@ -151,3 +151,3 @@ );

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_IMPORT_REJECTED.md
throw new SyntaxError(
throw SyntaxError(
`Possible import expression rejected at ${name}:${lineNumber}. (SES_IMPORT_REJECTED)`,

@@ -224,3 +224,3 @@ );

// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_EVAL_REJECTED.md
throw new SyntaxError(
throw SyntaxError(
`Possible direct eval expression rejected at ${name}:${lineNumber}. (SES_EVAL_REJECTED)`,

@@ -227,0 +227,0 @@ );

@@ -202,2 +202,3 @@ /**

quote(payload: any, spaces?: string | number): ToStringable;
bare(payload: any, spaces?: string | number): ToStringable;
makeAssert: MakeAssert;

@@ -204,0 +205,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc