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.16.0 to 0.17.0

src/eval-scope.js

27

CHANGELOG.md

@@ -6,2 +6,29 @@ # Change Log

## [0.17.0](https://github.com/endojs/endo/compare/ses@0.16.0...ses@0.17.0) (2022-10-24)
### ⚠ BREAKING CHANGES
* **ses:** Prevent surprising global unscopables behavior
* **ses:** Divide scope proxy into four layers
### Features
* **ses:** Revocable evalScope ([0187d1e](https://github.com/endojs/endo/commit/0187d1e3532cfc2f052619c46a8a6331a8c15ae8))
### Bug Fixes
* **ses:** Prevent surprising global unscopables behavior ([dcb8f5d](https://github.com/endojs/endo/commit/dcb8f5da2a453ac72b7f2cc3208f591a9c298402))
* **ses:** Protect necessary eval admission before it has been admitted ([3d022b1](https://github.com/endojs/endo/commit/3d022b1e1b34ff9b86cf6af236c499bfbe291298))
* **ses:** Typo in compartmentEvaluate ([d66db7a](https://github.com/endojs/endo/commit/d66db7a67fab6bdd36d18a931c6a9163e842c3fe))
* **ses:** Typo in scope-constants ([a4ee1ea](https://github.com/endojs/endo/commit/a4ee1ea5e54d894ad3a3ce0c5e42507f026199e6))
### Code Refactoring
* **ses:** Divide scope proxy into four layers ([37c4b4a](https://github.com/endojs/endo/commit/37c4b4a22996e33dd4b2a48c67ce649ba88e5528))
## [0.16.0](https://github.com/endojs/endo/compare/ses@0.15.23...ses@0.16.0) (2022-10-19)

@@ -8,0 +35,0 @@

User-visible changes in SES:
# v0.17.0 (2022-10-24)
- Previous versions of SES would leak the proxy used to isolate evaluated
code to functions added to the global object by guest code.
The value of `this` in such functions should be `undefined`, but that is not
possible to emulate in this shim.
This version changes the value of `this` in such functions to be the same as
`globalThis` of the compartment, as would be correct in sloppy mode.
- Removes experimental support for "known scope proxies".
# v0.16.0 (2022-10-19)

@@ -4,0 +14,0 @@

10

package.json
{
"name": "ses",
"version": "0.16.0",
"version": "0.17.0",
"description": "Hardened JavaScript for Fearless Cooperation",

@@ -56,3 +56,3 @@ "keywords": [

"lint:types": "tsc",
"prepublish": "yarn run clean && yarn build",
"prepare": "yarn run clean && yarn build",
"qt": "ava",

@@ -63,5 +63,5 @@ "test": "tsd && ava",

"devDependencies": {
"@endo/compartment-mapper": "^0.7.14",
"@endo/compartment-mapper": "^0.7.15",
"@endo/eslint-config": "^0.5.1",
"@endo/static-module-record": "^0.7.13",
"@endo/static-module-record": "^0.7.14",
"@endo/test262-runner": "^0.1.28",

@@ -184,3 +184,3 @@ "ava": "^3.12.1",

},
"gitHead": "8da6dc1002417c0f18cd43b351f8f62d7010260c"
"gitHead": "8fb324d8f13a0c6939dc0c1feb831f72298f1853"
}

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

matchAll: matchAllSymbol,
unscopables: unscopablesSymbol,
keyFor: symbolKeyFor,

@@ -79,0 +80,0 @@ for: symbolFor,

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

let { globalTransforms } = compartmentFields;
const {
globalObject,
globalLexicals,
knownScopeProxies,
} = compartmentFields;
const { globalObject, globalLexicals } = compartmentFields;

@@ -62,3 +58,2 @@ let localObject = globalLexicals;

sloppyGlobalsMode,
knownScopeProxies,
}));

@@ -71,3 +66,3 @@ }

export const compartmentEvaluate = (compartmentFields, source, options) => {
// Perform this check first to avoid unecessary sanitizing.
// Perform this check first to avoid unnecessary sanitizing.
// TODO Maybe relax string check and coerce instead:

@@ -74,0 +69,0 @@ // https://github.com/tc39/proposal-dynamic-code-brand-checks

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

WeakMap,
WeakSet,
arrayFilter,

@@ -22,5 +21,5 @@ arrayJoin,

weakmapSet,
weaksetHas,
} from './commons.js';
import {
setGlobalObjectSymbolUnscopables,
setGlobalObjectConstantProperties,

@@ -124,8 +123,2 @@ setGlobalObjectMutableProperties,

/* eslint-disable-next-line no-underscore-dangle */
__isKnownScopeProxy__(value) {
const { knownScopeProxies } = weakmapGet(privateFields, this);
return weaksetHas(knownScopeProxies, value);
},
module(specifier) {

@@ -283,2 +276,4 @@ if (typeof specifier !== 'string') {

setGlobalObjectSymbolUnscopables(globalObject);
// We must initialize all constant properties first because

@@ -291,3 +286,2 @@ // `makeSafeEvaluator` may use them to create optimized bindings

const knownScopeProxies = new WeakSet();
const { safeEvaluate } = makeSafeEvaluator({

@@ -298,3 +292,2 @@ globalObject,

sloppyGlobalsMode: false,
knownScopeProxies,
});

@@ -322,3 +315,2 @@

globalObject,
knownScopeProxies,
globalLexicals,

@@ -325,0 +317,0 @@ safeEvaluate,

@@ -1,2 +0,11 @@

import { defineProperty, objectHasOwnProperty, entries } from './commons.js';
import {
TypeError,
assign,
create,
defineProperty,
entries,
freeze,
objectHasOwnProperty,
unscopablesSymbol,
} from './commons.js';
import { makeEvalFunction } from './make-eval-function.js';

@@ -7,2 +16,32 @@ import { makeFunctionConstructor } from './make-function-constructor.js';

/**
* The host's ordinary global object is not provided by a `with` block, so
* assigning to Symbol.unscopables has no effect.
* Since this shim uses `with` blocks to create a confined lexical scope for
* guest programs, we cannot emulate the proper behavior.
* With this shim, assigning Symbol.unscopables causes the given lexical
* names to fall through to the terminal scope proxy.
* But, we can install this setter to prevent a program from proceding on
* this false assumption.
*
* @param {Object} globalObject
*/
export const setGlobalObjectSymbolUnscopables = globalObject => {
defineProperty(
globalObject,
unscopablesSymbol,
freeze(
assign(create(null), {
set: freeze(() => {
throw new TypeError(
`Cannot set Symbol.unscopables of a Compartment's globalThis`,
);
}),
enumerable: false,
configurable: false,
}),
),
);
};
/**
* setGlobalObjectConstantProperties()

@@ -9,0 +48,0 @@ * Initializes a new global object using a process similar to ECMA specifications

// Portions adapted from V8 - Copyright 2016 the V8 project authors.
// https://github.com/v8/v8/blob/master/src/builtins/builtins-function.cc
import {
WeakSet,
apply,
immutableObject,
proxyRevocable,
weaksetAdd,
} from './commons.js';
import { getScopeConstants } from './scope-constants.js';
import { createScopeHandler } from './scope-handler.js';
import { apply, freeze } from './commons.js';
import { strictScopeTerminator } from './strict-scope-terminator.js';
import { createSloppyGlobalsScopeTerminator } from './sloppy-globals-scope-terminator.js';
import { makeEvalScopeKit } from './eval-scope.js';
import { applyTransforms, mandatoryTransforms } from './transforms.js';
import { makeEvaluateFactory } from './make-evaluate-factory.js';
import { makeEvaluate } from './make-evaluate.js';
import { assert } from './error/assert.js';

@@ -29,3 +24,2 @@

* @param {bool} [options.sloppyGlobalsMode]
* @param {WeakSet} [options.knownScopeProxies]
*/

@@ -37,16 +31,15 @@ export const makeSafeEvaluator = ({

sloppyGlobalsMode = false,
knownScopeProxies = new WeakSet(),
} = {}) => {
const { scopeHandler, scopeController } = createScopeHandler(
const scopeTerminator = sloppyGlobalsMode
? createSloppyGlobalsScopeTerminator(globalObject)
: strictScopeTerminator;
const evalScopeKit = makeEvalScopeKit();
const { evalScope } = evalScopeKit;
const evaluateContext = freeze({
evalScope,
globalLexicals,
globalObject,
globalLexicals,
{
sloppyGlobalsMode,
},
);
const { proxy: scopeProxy, revoke: revokeScopeProxy } = proxyRevocable(
immutableObject,
scopeHandler,
);
weaksetAdd(knownScopeProxies, scopeProxy);
scopeTerminator,
});

@@ -57,7 +50,5 @@ // Defer creating the actual evaluator to first use.

let evaluate;
const makeEvaluate = () => {
const provideEvaluate = () => {
if (!evaluate) {
const constants = getScopeConstants(globalObject, globalLexicals);
const evaluateFactory = makeEvaluateFactory(constants);
evaluate = apply(evaluateFactory, scopeProxy, []);
evaluate = makeEvaluate(evaluateContext);
}

@@ -72,3 +63,3 @@ };

const safeEvaluate = (source, { localTransforms = [] } = {}) => {
makeEvaluate();
provideEvaluate();

@@ -83,5 +74,8 @@ // Execute the mandatory transforms last to ensure that any rewritten code

scopeController.allowNextEvalToBeUnsafe = true;
let err;
try {
// Allow next reference to eval produce the unsafe FERAL_EVAL.
// eslint-disable-next-line @endo/no-polymorphic-call
evalScopeKit.allowNextEvalToBeUnsafe();
// Ensure that "this" resolves to the safe global.

@@ -94,11 +88,10 @@ return apply(evaluate, globalObject, [source]);

} finally {
const unsafeEvalWasStillExposed = scopeController.allowNextEvalToBeUnsafe;
scopeController.allowNextEvalToBeUnsafe = false;
const unsafeEvalWasStillExposed = 'eval' in evalScope;
delete evalScope.eval;
if (unsafeEvalWasStillExposed) {
// Barring a defect in the SES shim, the scope proxy should allow the
// Barring a defect in the SES shim, the evalScope should allow the
// powerful, unsafe `eval` to be used by `evaluate` exactly once, as the
// very first name that it attempts to access from the lexical scope.
// A defect in the SES shim could throw an exception after we set
// `scopeController.allowNextEvalToBeUnsafe` and before `evaluate`
// calls `eval` internally.
// `evalScope.eval` and before `evaluate` calls `eval` internally.
// If we get here, SES is very broken.

@@ -113,3 +106,3 @@ // This condition is one where this vat is now hopelessly confused, and

// source code.
revokeScopeProxy();
evalScopeKit.revoked = { err };
// TODO A GOOD PLACE TO PANIC(), i.e., kill the vat incarnation.

@@ -116,0 +109,0 @@ // See https://github.com/Agoric/SES-shim/issues/490

@@ -80,3 +80,3 @@ import {

* identifierPattern
* Simplified validation of indentifier names: may only contain alphanumeric
* Simplified validation of identifier names: may only contain alphanumeric
* characters (or "$" or "_"), and may not start with a digit. This is safe

@@ -148,25 +148,26 @@ * and does not reduces the compatibility of the shim. The motivation for

* @param {Object} globalObject
* @param {Object} localObject
* @param {Object} globalLexicals
*/
export const getScopeConstants = (globalObject, localObject = {}) => {
export const getScopeConstants = (globalObject, globalLexicals = {}) => {
// getOwnPropertyNames() does ignore Symbols so we don't need to
// filter them out.
const globalNames = getOwnPropertyNames(globalObject);
const localNames = getOwnPropertyNames(localObject);
const globalObjectNames = getOwnPropertyNames(globalObject);
const globalLexicalNames = getOwnPropertyNames(globalLexicals);
// Collect all valid & immutable identifiers from the endowments.
const localConstants = arrayFilter(
localNames,
const globalLexicalConstants = arrayFilter(
globalLexicalNames,
name =>
isValidIdentifierName(name) && isImmutableDataProperty(localObject, name),
isValidIdentifierName(name) &&
isImmutableDataProperty(globalLexicals, name),
);
// Collect all valid & immutable identifiers from the global that
// are also not present in the endwoments (immutable or not).
const globalConstants = arrayFilter(
globalNames,
// are also not present in the endowments (immutable or not).
const globalObjectConstants = arrayFilter(
globalObjectNames,
name =>
// Can't define a constant: it would prevent a
// lookup on the endowments.
!arrayIncludes(localNames, name) &&
!arrayIncludes(globalLexicalNames, name) &&
isValidIdentifierName(name) &&

@@ -176,3 +177,6 @@ isImmutableDataProperty(globalObject, name),

return [...globalConstants, ...localConstants];
return {
globalObjectConstants,
globalLexicalConstants,
};
};

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

toString: fn,
__isKnownScopeProxy__: fn,
import: asyncFn,

@@ -1367,0 +1366,0 @@ load: asyncFn,

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