User-visible changes in SES:
- No changes yet.
- The
ses/lockdown
module and Rollup bundles now include a minimal implementation ofCompartment
that supportsevaluate
but not loading modules. This is sufficient for containment of JavaScript programs, including modules that have been pre-compiled to programs out-of-band, without entraining a full JavaScript parser framework. - Allows a compartment's
importHook
to return an "alias" if the returned static module record has a different specifier than requested. - Adds the
name
option to theCompartment
constructor andname
accessor to theCompartment
prototype. Errors that propagate through the module loader will be rethrown anew with the name of the module and compartment so they can be traced. At this time, the intermediate stacks of the causal chain are lost. endojs#440
- Adds a
moduleMapHook
option to theCompartment
constructor options. The module map hook can return values for themoduleMap
for any given module specifier, or returnundefined
to fall back to theimportHook
. This allows for wildcard linkage to other compartments. - Fix dependency version for
@agoric/transform-module
.
- Updates the whitelist to allow a
HandledPromise
global, which is provided by@agoric/eventual-send
, an early implementation of https://github.com/tc39/proposal-eventual-send. - Corrects our fix for the override mistake, so that it correctly emulates how assignment would work in the absence of the override mistake. A property created by assignment will now be a writable, enumerable, configurable data property, as it is for normal assignment.
- Creates a
ses/lockdown
module that only introduceslockdown
andharden
to global scope, for a much smaller payload thanses
, which entrains a JavaScript parser to support ECMAScript modules. - Adds the
load
method toCompartment
. Load allows a bundler or archiver to use theCompartment
API to gather the transitive dependencies of modules without executing them. - Adds support for third-party implementations of a
StaticModuleRecord
interface ({imports, execute}
).
- The
*Locale*
methods removed in the previous release are now restored by aliasing them to their non-locale equivalents.localeCompare
had no builtin non-locale equivalent, so we provide one. - Adds a TypeScript definition for
harden
.
- BREAKING CHANGE: The compartment
evaluate
method no longer accepts anendowments
option. Usecompartment.globalThis
,endowments
, orglobalLexicals
. If per-evaluationglobalLexicals
orendowments
are necessary, each evaluation will need a freshCompartment
. - BREAKING CHANGE: The
lockdown
function's deprecatednoTame*
options have been removed in favor of the*Taming
options introduced in version 0.8.0. - BREAKING CHANGE: The
.toLocale*
methods of Object/Number/BigInt/Date/String/Array/%TypedArray% were removed from SES environments. This includes methods namedtoLocaleString
,toLocaleDateString
,toLocaleTimeString
,toLocaleLowerCase
,toLocaleUpperCase
, andlocaleCompare
. These may be restored (in a modified form) in a future release. - The way
lockdown()
tames theError
constructor now cooperates with the V8 stack trace API to a degree that is permissible without breaking the integrity of applications that use it. - The Compartment constructor now accepts a
globalLexicals
option. The own enumerable properties of the global lexicals are captured and presented as constants in the scope of all calls toevaluate
and all modules. The global lexicals overshadow the global object.
-
Adds support for modules to Compartments.
-
SES no longer exports anything.
Compartment
,StaticModuleRecord
,lockdown
, andharden
are all introduced as properties ofglobalThis
. -
The
Compartment
global
getter is now namedglobalThis
, consistent with the specification proposal. -
The
Compartment
transforms
constructor option is now just an array of transform functions that accept and return program strings. Transforms can no longer introduceendowments
. The compartment constructor'sendowments
argument (first) and assigning properties toglobalThis
are the remaining supported ways to introduce endowments. -
Repair
Function.apply
andTypeError.message
(as well as.message
on all the other Error types), to tolerate what the npmes-abstract
module does. This allowstape
(version 4.x) to be loaded in a locked-down SES world, and also allows itst.throws
assertion to work.tape
(version 5.x) still has problems. #293 -
Replaces the old
noTame*
options tolockdown
with new*Taming
options. The old style had boolean values defaulting tofalse
. In the new style, each option supports at least the options'safe'
and'unsafe'
defaulting to'safe'
. As a transitional matter, this release still supports the old style as well, as another way to say the same thing. #326
- This version decouples lockdown and the Compartment constructor.
The Compartment constructor is now exported by
ses
(was previously only available as a property ofglobalThis
after lockdown). The Compartment constructor will also create "privileged" compartments when constructed before lockdown.
Bug fixes. This release fixes issues in RegExp and Error taming.
This release adds Node.js ESM support by upgrading @agoric/make-hardener to a hybrid version for most modern module systems.
-
Newless calls to the RegExp constructor now work after lockdown.
-
upgrade @agoric/make-hardener v0.0.8
Bug fixes.
This release addresses an exception observed where locking down fails because
SES cannot delete the prototype of the harden function.
This is addressed by upgrading @agoric/make-harden to version 0.0.7.
This release also restores fulls upport for importing SES as CommonJS, Node.js
ESM, and Node.js emulated ESM with the esm
package.
SECURITY UPDATE: This complete re-architecture which removes the realm-shim and resolve the associatd sandbox escapes related to leaking cross-realm intrinsics. All users should update to this version.
See [docs/ses-0.7.md].
SECURITY UPDATE: This release upgrades realms-shim to fix multiple sandbox escapes. All users should update to this version.
- upgrade to realms-shim v1.2.1
Non-security fixes:
- improve documentation
SECURITY UPDATE: This release upgrades realms-shim to fix multiple sandbox escapes. All users should update to this version.
- upgrade to realms-shim v1.2.0
Non-security fixes:
- add
SES.harden
to make hardening available from within the Realm. (#161)
No user-visible changes.
Use realms-shim as a normal package, not a git-submodule. Update eslint dependencies.
- SECURITY UPDATE: This release fixes a sandbox escape discovered in the realms-shim by GitHub user "XmiliaH", which works by causing an infinite loop and extracting the real function constructor from the RangeError exception object. See Agoric/realms-shim#48 for more details.
- Breaking change:
options.transforms
may no longer specifyendow()
transforms. Instead, userewrite()
, which can now modify endowments. See Agoric/realms-shim#38 for details. - Repair the "override mistake", with optional repair plan in
options.dataPropertiesToRepair
. See src/bundle/dataPropertiesToRepair.js and Agoric/SES#146 for details. options.sloppyGlobals
is rejected bymakeSESRootRealm()
, since all SES root realms are frozen.sloppyGlobals
can only be used in a new "Compartment", made by callingRealm.makeCompartment(options)
. See https://github.com/Agoric/SES/issues/142 Agoric/realms-shim#33 Agoric/realms-shim#30 for details.- Add
options.whitelist
to override the set of properties that are retained in the new realm. The default gives you SES, but it could be overridden to e.g. enforce a Jessie-only environment.
- Re-enable indirect eval. (#131)
Dependency updates only, no user-visible changes.
- The 'realms-shim' module, upon which SES depends, has been split out of the TC39 'proposal-realms' repository, and now lives in https://github.com/Agoric/realms-shim. It has not been released to NPM, rather SES incorporates it as a git submodule. (#110)
- The documentation is now hosted on ReadTheDocs at https://ses-secure-ecmascript.readthedocs.io/en/latest/ (#111, #117)
- SES.makeRootRealm() now accepts a 'transforms' option. This is a list of
{ endow, rewrite }
functions which can add/modify endowments and/or rewrite source code each time anevaluate()
is performed. (#125)
Thanks to Kate Sills, Dan Connolly, Michael Fig, and the ever-dependable Dependabot for additional fixes in this release.
INCOMPATIBLE API CHANGE: Starting with this release, the SES package exports
a single default object (named SES
, from which you can get the
SES.makeSESRootRealm()
function). Previously, it exported both a SES
object and the makeSESRootRealm
function.
Code which uses this package as an ES6 module must change its import from
import { SES } from 'ses';
to:
import SES from 'ses';
Similarly, for code which uses CommonJS-style, it must change from const { SES } = require('ses')
to:
const SES = require('ses')
The package now exports bundles in various flavors: CommonJS, ES6 Module, and browser-based UMD.
Other changes:
- whitelist Symbol.matchAll, to fix Chrome-v73 (Issue #90)
- change primary export #88
- improve documentation #66 #67
- add integration tests #85
- packaging: remove ses-shim.js, add other generated bundles
- update Realms shim to commit 0c00eb, to fix Browserify #79
- test against node v10/v11, switch from travis to circleci #73
- fix examples #102
Thanks to Matt Bell, Kate Sills, and Mark Miller for additional fixes in this release.
Improve usability.
- remove
Nat
anddef
from the global environment #45 - provide a helper function named
s.makeRequire()
to build arequire
endowment. This can be configured to enablerequire('@agoric/nat')
orrequire('@agoric/harden')
(among others), so the same code can work either inside or outside of a SES realm. For details of its configuration, see the comments in the commit which landed it. #13 - harden() comes from
@agoric/make-hardener
, which doesn't climb prototype/inheritance chains, but does complain if the prototype wasn't already known to harden(). This avoids the "Ice-9" freeze-the-world problem, and also serves to signal when an object from one realm is passed into the harden() of a different realm. #15 - harden() now shares a WeakSet of previously-hardened objects #4
- use harden() instead of def() #39
- SES no longer depends upon Nat, but uses it during unit tests. Client code
that wants Nat should use
require('@agoric/nat')
. #45 - Include AsyncIteratorPrototype in the set of anonIntrinsics #58
- use eslint to format all SES code
Improves security and functionality.
This fixes all known confinement leaks:
- We now freeze AsyncGeneratorFunction and AsyncFunction, the last of the "anonymous" intrinsics (which are reachable by syntax but not simple property lookup). In the previous release, attacker code could modify their behavior (which defender code might have been relying upon) or use them as a communication channel. (#3, #41)
- We now remove all unknown properties from the global object, using a
special list of ones that are safe to expose. This protects us from
surprising platform-specific objects, or newly-added standard JS objects
that have not yet been examined for safety. The 'Intl' object is currently
removed by this check (and
intlMode: "allow"
has been removed), but may be brought back in a future release. (#26) - RegExp.prototype.compile is removed unconditionally (even if regexpMode: "allow" is set), because it violates the semantics of Object.freeze
It also improves usability:
- Uncaught exceptions in Node.js are now rendered correctly when the
errorStackMode: "allow"
option is enabled. In the previous release, such exceptions were always displayed as "undefined", which was particularly unhelpful. If your program is abruptly exiting with "undefined", try turning this option on while you're debugging. But don't leave it on, because it probably enables a confinement breach. - SES is an ES6 module, but should now be importable with
require()
by other code which is unaware of ES6 modules, because it now uses theesm
module internally. (#32) console.log
is now available within the confined code, if theconsoleMode: "allow"
option is enabled. If this is disabled,console.log()
will throw aTypeError
(sinceconsole
is undefined, it has nolog
property). Many otherconsole
methods (but not all) are exposed too. (#35)
SES now requires Node.js version 10 or later.
Improves confinement, small API changes.
The options passed as SES.makeSESRootRealm(options)
have changed:
options.dateNowMode="allow"
allowsDate.now()
andnew Date()
to work normally, otherwise they return NaNoptions.mathRandomMode="allow"
allowsMath.random()
to work normally (nondeterministically), else it will throw an Erroroptions.intlMode="allow"
letsIntl.DateTimeFormat()
,Intl.NumberFormat()
, andIntl.getCanonicalLocales()
to work normally, else they throw Errorsoptions.errorStackMode="allow"
exposesError.prototype.stack
andError.captureStackTrace
(on platforms that support them), otherwise they are suppressed. Note that these could be used to break confinement, not just access nondeterminism.
Previously the only option honored was options.dateNowTrap = false
The suppression of Error.captureStackTrace
is new in this release. This
release also suppresses RegExp.prototype.compile
and properties like
RegExp.$1
which cause some surprising behavior.
SES.def
and SES.Nat
are exported, so they can be used by non-confined
code (mostly in tests). def(obj)
makes an object defensive, by freezing
it's external API surface (anything reachable by property lookup and
prototype traversal). Nat(num)
throws an error unless its argument is a
natural number (a non-negative integer small enough to remain an integer
inside a Javascript Number
type). Both are important for defensive
programming.
Adds Nat and SES.confineExpr.
Nat(val)
ensures the value is a natural (non-negative) integerSES.confineExpr(expr)
makes it easy to start with a function object, turn it into a string, then into a new function inside the SES realm.
This also updates the challenge page to fix a demo vulnerability (#8).
- npm name is now 'ses'
- update to current proposal-realms
first preliminary release