CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ses

Hardened JavaScript for fearless cooperation through secure execution contexts and object-capability security

Pending
Overview
Eval results
Files

environment-hardening.mddocs/

Environment Hardening

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.

Capabilities

Lockdown Function

Primary initialization function that hardens the JavaScript environment and sets up the global harden function.

/**
 * Hardens the JavaScript environment by repairing and freezing intrinsics
 * @param options - Configuration options for hardening behavior
 */
function lockdown(options?: LockdownOptions): void;

Usage Examples:

import 'ses';

// Basic lockdown with default settings
lockdown();

// Lockdown with custom configuration
lockdown({
  errorTaming: 'safe',
  stackFiltering: 'concise',
  consoleTaming: 'safe'
});

// Check that intrinsics are frozen
console.log(Object.isFrozen([].__proto__)); // true

Repair Intrinsics

Lower-level function that repairs JavaScript intrinsics without immediately hardening them, providing more control over the hardening process.

/**
 * Repairs JavaScript intrinsics and returns a function to harden them
 * @param options - Configuration options for repair behavior
 * @returns Function that when called will harden intrinsics and expose global harden
 */
function repairIntrinsics(options?: LockdownOptions): HardenIntrinsics;

type HardenIntrinsics = () => Harden;

Usage Examples:

import 'ses';

// Repair intrinsics first
const hardenIntrinsics = repairIntrinsics({
  errorTaming: 'safe'
});

// Later, harden the intrinsics and get the harden function
const harden = hardenIntrinsics();

// Now harden is available globally
console.log(typeof globalThis.harden); // 'function'

Harden Intrinsics

Function that hardens all JavaScript intrinsics and exposes the global harden function.

/**
 * Hardens all JavaScript intrinsics and returns the harden function
 * @returns The harden function for making object graphs tamper-proof
 */
function hardenIntrinsics(): Harden;

Harden Function

Makes object graphs tamper-proof by recursively freezing all objects in the transitive closure.

/**
 * Recursively freezes an object graph to make it tamper-proof
 * @param value - The object or value to harden
 * @returns The same object, now hardened
 */
function harden<T>(value: T): T;

Usage Examples:

import 'ses';

lockdown();

// Harden a simple object
const data = harden({ 
  message: "Hello",
  count: 42 
});

console.log(Object.isFrozen(data)); // true

// Harden a capability object
let counter = 0;
const capability = harden({
  increment() {
    counter++;
  },
  getValue() {
    return counter;
  }
});

// The surface is frozen, but closures still work
console.log(Object.isFrozen(capability)); // true
console.log(Object.isFrozen(capability.increment)); // true
capability.increment(); // Still works!
console.log(capability.getValue()); // 1

Configuration Options

LockdownOptions Interface

Comprehensive configuration for controlling SES hardening behavior.

interface LockdownOptions {
  /** Controls RegExp taming - 'safe' removes deprecated compile method */
  regExpTaming?: 'safe' | 'unsafe';
  
  /** Controls locale method taming - 'safe' replaces with generic versions */
  localeTaming?: 'safe' | 'unsafe';
  
  /** Controls console taming - 'safe' enables causal console logging */
  consoleTaming?: 'safe' | 'unsafe';
  
  /** Controls error trapping behavior for unhandled errors */
  errorTrapping?: 'platform' | 'exit' | 'abort' | 'report' | 'none';
  
  /** Controls where errors are reported */
  reporting?: 'platform' | 'console' | 'none';
  
  /** Controls unhandled promise rejection handling */
  unhandledRejectionTrapping?: 'report' | 'none';
  
  /** Controls error object taming for stack trace security */
  errorTaming?: 'safe' | 'unsafe' | 'unsafe-debug';
  
  /** Controls eval function availability and safety */
  evalTaming?: 'safe-eval' | 'unsafe-eval' | 'no-eval' | 'safeEval' | 'unsafeEval' | 'noEval';
  
  /** Controls stack trace filtering in error messages */
  stackFiltering?: 'concise' | 'omit-frames' | 'shorten-paths' | 'verbose';
  
  /** Controls property override protection level */
  overrideTaming?: 'moderate' | 'min' | 'severe';
  
  /** Array of property names to debug override issues */
  overrideDebug?: Array<string>;
  
  /** Controls Node.js domain module taming */
  domainTaming?: 'safe' | 'unsafe';
  
  /** Controls legacy regenerator runtime handling */
  legacyRegeneratorRuntimeTaming?: 'safe' | 'unsafe-ignore';
  
  /** Internal harden taming option */
  __hardenTaming__?: 'safe' | 'unsafe';
}

Option Details:

Error and Stack Options:

  • errorTaming: 'safe' - Hides V8 stack traces from errors but console can still see them
  • stackFiltering: 'concise' - Provides clean, readable stack traces
  • reporting: 'console' - Reports errors to console for debugging

Security Options:

  • regExpTaming: 'safe' - Removes deprecated RegExp.compile method
  • localeTaming: 'safe' - Replaces locale-revealing methods with generic versions
  • overrideTaming: 'moderate' - Prevents property override mistakes at moderate level

Eval and Code Execution:

  • evalTaming: 'safe-eval' - Allows eval but in safe form within compartments
  • evalTaming: 'no-eval' - Completely disables eval functionality

Security Properties

Prototype Pollution Protection

SES prevents prototype pollution by freezing all intrinsic objects:

import 'ses';

lockdown();

// This would normally pollute Object.prototype
try {
  Object.prototype.polluted = 'bad';
} catch (error) {
  console.log('Prevented prototype pollution!');
}

// Intrinsics are frozen
console.log(Object.isFrozen(Object.prototype)); // true
console.log(Object.isFrozen(Array.prototype)); // true

Supply Chain Attack Mitigation

By freezing intrinsics, SES prevents malicious code from modifying built-in methods:

import 'ses';

lockdown();

// Malicious code cannot override built-in methods
try {
  Array.prototype.map = function() { 
    console.log('Hijacked!'); 
    return []; 
  };
} catch (error) {
  console.log('Supply chain attack prevented!');
}

Controlled Global Environment

SES provides a controlled global environment where dangerous capabilities are removed by default:

import 'ses';

lockdown();

// Dangerous time-based functions are not available by default in compartments
const compartment = new Compartment();
const result = compartment.evaluate(`
  typeof Date.now === 'undefined' // true - no timing oracle
  && typeof Math.random === 'undefined' // true - no PRNG
`);
console.log(result); // true

Install with Tessl CLI

npx tessl i tessl/npm-ses

docs

assertions.md

compartments.md

environment-hardening.md

index.md

modules.md

tools.md

tile.json