Hardened JavaScript for fearless cooperation through secure execution contexts and object-capability security
npx @tessl/cli install tessl/npm-ses@1.14.00
# SES (Secure ECMAScript)
1
2
SES is a hardened JavaScript library that enables secure execution of third-party code through compartmentalization and object-capability security. It provides isolated execution contexts (compartments) with their own global objects while sharing frozen intrinsics to maintain compatibility, enforces strict mode for enhanced security, and implements the Principle of Least Authority (POLA) by providing compartments with no ambient authority by default.
3
4
## Package Information
5
6
- **Package Name**: ses
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install ses`
10
11
## Core Imports
12
13
```javascript
14
import 'ses';
15
// This imports and installs all SES functionality globally
16
```
17
18
For CommonJS:
19
20
```javascript
21
require('ses');
22
// This imports and installs all SES functionality globally
23
```
24
25
Individual shims can also be imported separately:
26
27
```javascript
28
import 'ses/lockdown-shim.js'; // Just lockdown functionality
29
import 'ses/compartment-shim.js'; // Just Compartment constructor
30
import 'ses/assert-shim.js'; // Just assert functionality
31
import 'ses/console-shim.js'; // Just console enhancements
32
```
33
34
For CommonJS:
35
36
```javascript
37
require('ses/lockdown-shim.js'); // Just lockdown functionality
38
require('ses/compartment-shim.js'); // Just Compartment constructor
39
require('ses/assert-shim.js'); // Just assert functionality
40
require('ses/console-shim.js'); // Just console enhancements
41
```
42
43
For tools and utilities:
44
45
```javascript
46
import { transforms, scopeTerminators } from 'ses/tools.js';
47
```
48
49
For CommonJS:
50
51
```javascript
52
const { transforms, scopeTerminators } = require('ses/tools.js');
53
```
54
55
## Basic Usage
56
57
```javascript
58
import 'ses';
59
60
// Step 1: Harden the environment
61
lockdown();
62
63
// Step 2: Create isolated compartments for untrusted code
64
const compartment = new Compartment({
65
globals: {
66
console: harden(console),
67
// Only provide necessary capabilities
68
},
69
__options__: true, // temporary migration affordance
70
});
71
72
// Step 3: Safely execute code
73
const result = compartment.evaluate(`
74
// This code runs in isolation with limited capabilities
75
const data = { message: "Hello from compartment!" };
76
harden(data);
77
data;
78
`);
79
80
// Step 4: Use harden to make objects tamper-proof
81
const capability = harden({
82
getValue: () => "secure value",
83
increment: () => { counter++; }
84
});
85
```
86
87
## Architecture
88
89
SES is built around several key security concepts:
90
91
- **Compartmentalization**: Isolated execution contexts with separate global objects but shared intrinsics
92
- **Object-Capability Security**: Fine-grained authority control through explicit capability passing
93
- **Hardened Intrinsics**: Frozen JavaScript built-ins prevent prototype pollution and supply chain attacks
94
- **Principle of Least Authority (POLA)**: Compartments start with minimal capabilities by default
95
- **Tamper-Proof Objects**: `harden()` recursively freezes object graphs to prevent modification
96
97
## Capabilities
98
99
### Environment Hardening
100
101
Core functionality for hardening the JavaScript environment against prototype pollution and supply chain attacks.
102
103
```javascript { .api }
104
function lockdown(options?: LockdownOptions): void;
105
function repairIntrinsics(options?: LockdownOptions): HardenIntrinsics;
106
function hardenIntrinsics(): Harden;
107
function harden<T>(value: T): T;
108
```
109
110
[Environment Hardening](./environment-hardening.md)
111
112
### Compartments
113
114
Isolated execution contexts for running untrusted code with controlled capabilities and communication channels.
115
116
```javascript { .api }
117
class Compartment {
118
constructor(options?: CompartmentOptions & { __options__: true });
119
evaluate(code: string, options?: EvaluateOptions): any;
120
import(specifier: string | null): Promise<{ namespace: ModuleExportsNamespace }>;
121
importNow(specifier: string): ModuleExportsNamespace;
122
load(specifier: string): Promise<void>;
123
module(specifier: string): ModuleExportsNamespace;
124
get globalThis(): Record<PropertyKey, any>;
125
get name(): string;
126
}
127
```
128
129
[Compartments](./compartments.md)
130
131
### Assertion System
132
133
Enhanced assertion library with detailed error reporting and causal console integration.
134
135
```javascript { .api }
136
function assert(flag: any, details?: Details, errConstructor?: GenericErrorConstructor, options?: AssertMakeErrorOptions): asserts flag;
137
138
interface AssertionFunctions {
139
typeof: AssertTypeof;
140
equal<T>(actual: unknown, expected: T, details?: Details, errConstructor?: GenericErrorConstructor, options?: AssertMakeErrorOptions): asserts actual is T;
141
string(specimen: any, details?: Details): asserts specimen is string;
142
fail(details?: Details, errConstructor?: GenericErrorConstructor, options?: AssertMakeErrorOptions): never;
143
}
144
```
145
146
[Assertion System](./assertions.md)
147
148
### Module System
149
150
Advanced module loading with hooks for custom resolution, transformation, and cross-compartment module sharing.
151
152
```javascript { .api }
153
type ImportHook = (moduleSpecifier: string) => Promise<ModuleDescriptor>;
154
type ImportNowHook = (moduleSpecifier: string) => ModuleDescriptor | undefined;
155
type ResolveHook = (importSpecifier: string, referrerSpecifier: string) => string;
156
type ModuleMapHook = (moduleSpecifier: string) => ModuleDescriptor | undefined;
157
```
158
159
[Module System](./modules.md)
160
161
### Development Tools
162
163
Source transformation and scope manipulation utilities for advanced use cases.
164
165
```javascript { .api }
166
interface TransformTools {
167
transforms: Record<string, Transform>;
168
}
169
170
interface ScopeTerminators {
171
strictScopeTerminator: any;
172
createSloppyGlobalsScopeTerminator: () => any;
173
}
174
```
175
176
[Development Tools](./tools.md)
177
178
## Types
179
180
### Core Configuration Types
181
182
```javascript { .api }
183
interface LockdownOptions {
184
regExpTaming?: 'safe' | 'unsafe';
185
localeTaming?: 'safe' | 'unsafe';
186
consoleTaming?: 'safe' | 'unsafe';
187
errorTrapping?: 'platform' | 'exit' | 'abort' | 'report' | 'none';
188
reporting?: 'platform' | 'console' | 'none';
189
unhandledRejectionTrapping?: 'report' | 'none';
190
errorTaming?: 'safe' | 'unsafe' | 'unsafe-debug';
191
evalTaming?: 'safe-eval' | 'unsafe-eval' | 'no-eval' | 'safeEval' | 'unsafeEval' | 'noEval';
192
stackFiltering?: 'concise' | 'omit-frames' | 'shorten-paths' | 'verbose';
193
overrideTaming?: 'moderate' | 'min' | 'severe';
194
overrideDebug?: Array<string>;
195
domainTaming?: 'safe' | 'unsafe';
196
legacyRegeneratorRuntimeTaming?: 'safe' | 'unsafe-ignore';
197
__hardenTaming__?: 'safe' | 'unsafe';
198
}
199
200
interface CompartmentOptions {
201
name?: string;
202
transforms?: Array<Transform>;
203
moduleMapHook?: ModuleMapHook;
204
importHook?: ImportHook;
205
importNowHook?: ImportNowHook;
206
importMetaHook?: ImportMetaHook;
207
resolveHook?: ResolveHook;
208
globals?: Map<string, any>;
209
modules?: Map<string, ModuleDescriptor>;
210
__shimTransforms__?: Array<Transform>;
211
__noNamespaceBox__?: boolean;
212
__native__?: boolean;
213
noAggregateLoadErrors?: boolean;
214
}
215
216
interface EvaluateOptions {
217
transforms?: Array<Transform>;
218
sloppyGlobalsMode?: boolean;
219
__moduleShimLexicals__?: Record<string, any>;
220
__evadeHtmlCommentTest__?: boolean;
221
__rejectSomeDirectEvalExpressions__?: boolean;
222
}
223
```
224
225
### Module System Types
226
227
```javascript { .api }
228
type ModuleExportsNamespace = Record<string, any>;
229
230
type __LiveExportMap__ = Record<string, [string, boolean]>;
231
type __FixedExportMap__ = Record<string, [string]>;
232
type __ReexportMap__ = Record<string, Array<[string, string]>>;
233
234
interface PrecompiledModuleSource {
235
imports: Array<string>;
236
exports: Array<string>;
237
reexports: Array<string>;
238
__syncModuleProgram__: string;
239
__liveExportMap__: __LiveExportMap__;
240
__fixedExportMap__: __FixedExportMap__;
241
__reexportMap__: __ReexportMap__;
242
}
243
244
interface VirtualModuleSource {
245
imports: Array<string>;
246
exports: Array<string>;
247
execute(exportsTarget: Record<string, any>, compartment: Compartment, resolvedImports: Record<string, string>): void;
248
}
249
250
type ModuleSource = PrecompiledModuleSource | VirtualModuleSource;
251
252
type ModuleDescriptor = SourceModuleDescriptor | NamespaceModuleDescriptor | RecordModuleDescriptor | ModuleExportsNamespace | VirtualModuleSource | PrecompiledModuleSource | string;
253
254
interface SourceModuleDescriptor {
255
source: string | ModuleSource;
256
specifier?: string;
257
importMeta?: any;
258
compartment?: Compartment;
259
}
260
261
interface NamespaceModuleDescriptor {
262
namespace: string | ModuleExportsNamespace;
263
compartment?: Compartment;
264
}
265
266
interface RecordModuleDescriptor {
267
specifier: string;
268
record?: ModuleSource;
269
importMeta?: any;
270
compartment?: Compartment;
271
}
272
```
273
274
### Hook Types
275
276
```javascript { .api }
277
type Transform = (source: string) => string;
278
type ResolveHook = (importSpecifier: string, referrerSpecifier: string) => string;
279
type ImportHook = (moduleSpecifier: string) => Promise<ModuleDescriptor>;
280
type ImportNowHook = (moduleSpecifier: string) => ModuleDescriptor | undefined;
281
type ModuleMapHook = (moduleSpecifier: string) => ModuleDescriptor | undefined;
282
type ImportMetaHook = (moduleSpecifier: string, importMeta: ImportMeta) => void;
283
```
284
285
### Assertion System Types
286
287
```javascript { .api }
288
type Harden = <T>(value: T) => T;
289
type Details = string | DetailsToken;
290
type DetailsToken = Record<any, never>;
291
292
interface AssertMakeErrorOptions {
293
errorName?: string;
294
cause?: Error;
295
errors?: Error[];
296
sanitize?: boolean;
297
}
298
299
type GenericErrorConstructor = ErrorConstructor | AggregateErrorConstructor;
300
type Raise = (reason: Error) => void;
301
type MakeAssert = (raise?: Raise, unredacted?: boolean) => Assert;
302
303
interface StringablePayload {
304
toString(): string;
305
}
306
```