or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdcompartments.mdenvironment-hardening.mdindex.mdmodules.mdtools.md

environment-hardening.mddocs/

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

```