0
# Environment Hardening
1
2
Core functionality for hardening the JavaScript environment against prototype pollution, supply chain attacks, and other security vulnerabilities through freezing intrinsics and controlling access to dangerous capabilities.
3
4
## Capabilities
5
6
### Lockdown Function
7
8
Primary initialization function that hardens the JavaScript environment and sets up the global `harden` function.
9
10
```javascript { .api }
11
/**
12
* Hardens the JavaScript environment by repairing and freezing intrinsics
13
* @param options - Configuration options for hardening behavior
14
*/
15
function lockdown(options?: LockdownOptions): void;
16
```
17
18
**Usage Examples:**
19
20
```javascript
21
import 'ses';
22
23
// Basic lockdown with default settings
24
lockdown();
25
26
// Lockdown with custom configuration
27
lockdown({
28
errorTaming: 'safe',
29
stackFiltering: 'concise',
30
consoleTaming: 'safe'
31
});
32
33
// Check that intrinsics are frozen
34
console.log(Object.isFrozen([].__proto__)); // true
35
```
36
37
### Repair Intrinsics
38
39
Lower-level function that repairs JavaScript intrinsics without immediately hardening them, providing more control over the hardening process.
40
41
```javascript { .api }
42
/**
43
* Repairs JavaScript intrinsics and returns a function to harden them
44
* @param options - Configuration options for repair behavior
45
* @returns Function that when called will harden intrinsics and expose global harden
46
*/
47
function repairIntrinsics(options?: LockdownOptions): HardenIntrinsics;
48
49
type HardenIntrinsics = () => Harden;
50
```
51
52
**Usage Examples:**
53
54
```javascript
55
import 'ses';
56
57
// Repair intrinsics first
58
const hardenIntrinsics = repairIntrinsics({
59
errorTaming: 'safe'
60
});
61
62
// Later, harden the intrinsics and get the harden function
63
const harden = hardenIntrinsics();
64
65
// Now harden is available globally
66
console.log(typeof globalThis.harden); // 'function'
67
```
68
69
### Harden Intrinsics
70
71
Function that hardens all JavaScript intrinsics and exposes the global `harden` function.
72
73
```javascript { .api }
74
/**
75
* Hardens all JavaScript intrinsics and returns the harden function
76
* @returns The harden function for making object graphs tamper-proof
77
*/
78
function hardenIntrinsics(): Harden;
79
```
80
81
### Harden Function
82
83
Makes object graphs tamper-proof by recursively freezing all objects in the transitive closure.
84
85
```javascript { .api }
86
/**
87
* Recursively freezes an object graph to make it tamper-proof
88
* @param value - The object or value to harden
89
* @returns The same object, now hardened
90
*/
91
function harden<T>(value: T): T;
92
```
93
94
**Usage Examples:**
95
96
```javascript
97
import 'ses';
98
99
lockdown();
100
101
// Harden a simple object
102
const data = harden({
103
message: "Hello",
104
count: 42
105
});
106
107
console.log(Object.isFrozen(data)); // true
108
109
// Harden a capability object
110
let counter = 0;
111
const capability = harden({
112
increment() {
113
counter++;
114
},
115
getValue() {
116
return counter;
117
}
118
});
119
120
// The surface is frozen, but closures still work
121
console.log(Object.isFrozen(capability)); // true
122
console.log(Object.isFrozen(capability.increment)); // true
123
capability.increment(); // Still works!
124
console.log(capability.getValue()); // 1
125
```
126
127
## Configuration Options
128
129
### LockdownOptions Interface
130
131
Comprehensive configuration for controlling SES hardening behavior.
132
133
```javascript { .api }
134
interface LockdownOptions {
135
/** Controls RegExp taming - 'safe' removes deprecated compile method */
136
regExpTaming?: 'safe' | 'unsafe';
137
138
/** Controls locale method taming - 'safe' replaces with generic versions */
139
localeTaming?: 'safe' | 'unsafe';
140
141
/** Controls console taming - 'safe' enables causal console logging */
142
consoleTaming?: 'safe' | 'unsafe';
143
144
/** Controls error trapping behavior for unhandled errors */
145
errorTrapping?: 'platform' | 'exit' | 'abort' | 'report' | 'none';
146
147
/** Controls where errors are reported */
148
reporting?: 'platform' | 'console' | 'none';
149
150
/** Controls unhandled promise rejection handling */
151
unhandledRejectionTrapping?: 'report' | 'none';
152
153
/** Controls error object taming for stack trace security */
154
errorTaming?: 'safe' | 'unsafe' | 'unsafe-debug';
155
156
/** Controls eval function availability and safety */
157
evalTaming?: 'safe-eval' | 'unsafe-eval' | 'no-eval' | 'safeEval' | 'unsafeEval' | 'noEval';
158
159
/** Controls stack trace filtering in error messages */
160
stackFiltering?: 'concise' | 'omit-frames' | 'shorten-paths' | 'verbose';
161
162
/** Controls property override protection level */
163
overrideTaming?: 'moderate' | 'min' | 'severe';
164
165
/** Array of property names to debug override issues */
166
overrideDebug?: Array<string>;
167
168
/** Controls Node.js domain module taming */
169
domainTaming?: 'safe' | 'unsafe';
170
171
/** Controls legacy regenerator runtime handling */
172
legacyRegeneratorRuntimeTaming?: 'safe' | 'unsafe-ignore';
173
174
/** Internal harden taming option */
175
__hardenTaming__?: 'safe' | 'unsafe';
176
}
177
```
178
179
**Option Details:**
180
181
**Error and Stack Options:**
182
- `errorTaming: 'safe'` - Hides V8 stack traces from errors but console can still see them
183
- `stackFiltering: 'concise'` - Provides clean, readable stack traces
184
- `reporting: 'console'` - Reports errors to console for debugging
185
186
**Security Options:**
187
- `regExpTaming: 'safe'` - Removes deprecated RegExp.compile method
188
- `localeTaming: 'safe'` - Replaces locale-revealing methods with generic versions
189
- `overrideTaming: 'moderate'` - Prevents property override mistakes at moderate level
190
191
**Eval and Code Execution:**
192
- `evalTaming: 'safe-eval'` - Allows eval but in safe form within compartments
193
- `evalTaming: 'no-eval'` - Completely disables eval functionality
194
195
## Security Properties
196
197
### Prototype Pollution Protection
198
199
SES prevents prototype pollution by freezing all intrinsic objects:
200
201
```javascript
202
import 'ses';
203
204
lockdown();
205
206
// This would normally pollute Object.prototype
207
try {
208
Object.prototype.polluted = 'bad';
209
} catch (error) {
210
console.log('Prevented prototype pollution!');
211
}
212
213
// Intrinsics are frozen
214
console.log(Object.isFrozen(Object.prototype)); // true
215
console.log(Object.isFrozen(Array.prototype)); // true
216
```
217
218
### Supply Chain Attack Mitigation
219
220
By freezing intrinsics, SES prevents malicious code from modifying built-in methods:
221
222
```javascript
223
import 'ses';
224
225
lockdown();
226
227
// Malicious code cannot override built-in methods
228
try {
229
Array.prototype.map = function() {
230
console.log('Hijacked!');
231
return [];
232
};
233
} catch (error) {
234
console.log('Supply chain attack prevented!');
235
}
236
```
237
238
### Controlled Global Environment
239
240
SES provides a controlled global environment where dangerous capabilities are removed by default:
241
242
```javascript
243
import 'ses';
244
245
lockdown();
246
247
// Dangerous time-based functions are not available by default in compartments
248
const compartment = new Compartment();
249
const result = compartment.evaluate(`
250
typeof Date.now === 'undefined' // true - no timing oracle
251
&& typeof Math.random === 'undefined' // true - no PRNG
252
`);
253
console.log(result); // true
254
```