Registry / auth-security / ses
library2.0.0jsnpmunverified

SES (Secure EcmaScript) is a JavaScript shim providing a hardened environment for robust security and fearless cooperation. It implements Hardened JavaScript, a subset of JavaScript proposed to ECMA TC39, designed to prevent prototype pollution and other common vulnerabilities. The current stable version, 2.0.0, focuses on plugging side-channel attacks and refining security guarantees. SES operates by 'locking down' the global environment, freezing intrinsic objects, and providing the `Compartment` constructor for creating isolated execution contexts. Each `Compartment` has its own global object and module system but shares hardened, immutable primordials with other compartments. This approach ensures that mutually suspicious code can interact safely via object-capability (ocap) principles, where powers are explicitly granted. The package maintains an active release cadence, with frequent updates across the broader `@endo` ecosystem. Key differentiators include its comprehensive protection against tampering with built-in objects, enforcement of strict mode, and its utility in sandboxing third-party code for applications like blockchain smart contracts and browser extensions, notably used by Agoric and MetaMask.

npm install ses
INSTALL
IMPORT
SIG · SES
S
ses
auth-securityjavascriptv2.0.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

lockdown
import { lockdown } from 'ses';
const lockdown = require('ses').lockdown;
While CommonJS `require` works, ESM `import` is the recommended pattern. `lockdown()` is typically called once globally.
Compartment
import { Compartment } from 'ses';
const Compartment = require('ses').Compartment;
The `Compartment` constructor is unavailable before `lockdown()` is called to ensure a hardened environment.
harden
import { harden } from 'ses';
const harden = require('ses').harden;
Used to recursively freeze objects and their reachable properties, making them tamper-proof. It's automatically applied to many intrinsics by `lockdown()`.
Global Lockdown
import 'ses'; // Immediately hardens the global environment lockdown(); // Explicitly calls the global lockdown function
require('ses'); // Only imports, does not automatically call lockdown
Importing 'ses' as a side effect calls `lockdown()` in some environments, but it's best practice to explicitly call `lockdown()` after import.

Demonstrates locking down the global environment and securely executing untrusted TypeScript code within an isolated Compartment, explicitly granting limited capabilities like logging and a custom greeting function. It also shows how attempts at prototype pollution or unauthorized global access are prevented.

import { lockdown, Compartment, harden } from 'ses'; // Step 1: Lock down the global environment to prevent tampering. // This should be done as early as possible in your application's lifecycle. lockdown(); console.log('Global environment locked down.'); // Step 2: Create a new Compartment for secure execution of untrusted code. // Compartments are isolated and by default have no ambient authority (e.g., no `fetch`). const untrustedCompartment = new Compartment({ globals: { // Grant specific global capabilities to the compartment. log: harden(console.log), greet: harden((name: string) => `Hello, ${name} from compartment!\n`), }, }); // Step 3: Evaluate untrusted code within the compartment. // The code only has access to its explicit globals and hardened intrinsics. const untrustedCode = ` try { log(greet('World')); // Attempting to access unauthorized globals will fail. // console.error('This should not be accessible.'); // new Function('return this')().alert('Attempted to access window!'); log('Attempting to modify Object.prototype...'); Object.prototype.evil = 'muahaha'; // This will fail due to lockdown } catch (e: any) { log('Caught expected error: ' + e.message); } const func = new Function('return 1 + 1;'); // This will throw after lockdown `; try { untrustedCompartment.evaluate(untrustedCode); } catch (e: any) { console.error('Error evaluating untrusted code:', e.message); } // Verify global prototype pollution did not occur in the main realm if (Object.prototype.hasOwnProperty('evil')) { console.error('Prototype pollution detected in main realm!'); } else { console.log('Main realm is still secure.'); }
Debug
Known issues
breakingVersion 2.0.0 includes a major fix for a NaN side-channel vulnerability in JavaScript. This change prevents the leakage of NaN bit encodings via shared TypedArray views of a common ArrayBuffer, which could potentially expose sensitive information. Users should upgrade to prevent this subtle information leak.
fix
Upgrade `ses` to version 2.0.0 or higher. Ensure your application architecture accounts for the strictness introduced by `lockdown()` regarding numeric representations.
affects: >=2.0.0
gotchaCalling `lockdown()` irreversibly modifies the global JavaScript environment. It freezes all intrinsic objects and functions, preventing any further prototype pollution or global tampering. It must be called once and as early as possible in the application's lifecycle, before any untrusted code or potentially harmful shims are loaded.
fix
Ensure `lockdown()` is the very first significant operation in your main entry point. Avoid calling it multiple times or after third-party libraries have initialized, as they might expect a mutable global environment.
affects: >=1.0.0
gotchaAfter `lockdown()` is invoked, the `Function` constructor and similar evaluators (e.g., `eval`, `setTimeout(string)`) become 'tamed' in the global realm, meaning they will throw an error when attempting to evaluate arbitrary source code. This is a critical security feature to prevent direct arbitrary code execution. Within a `Compartment`, its own `Function` constructor evaluates code only within that compartment's global scope.
fix
Do not rely on global `new Function()` or `eval()` after `lockdown()`. Instead, use `compartment.evaluate(code)` for code evaluation within an explicitly controlled, isolated environment. For dynamic module loading, use `compartment.import()` or `compartment.moduleMapHook`.
affects: >=1.0.0
gotchaCompartments operate under the Principle of Least Authority (POLA). By default, a `Compartment` receives no ambient authority, meaning it does not automatically have access to host-provided APIs like `fetch`, `localStorage`, `console`, or `process`.
fix
Explicitly pass any required ambient authority (e.g., `console.log`, `fetch`) into the `Compartment`'s `globals` or via its `importHook` and `moduleMap`. Use `harden()` on any objects passed into the `globals` to prevent the compartment from tampering with them.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: Cannot assign to read only property 'prototype' of object '#<Object>' (or similar 'Cannot assign to read only property' errors)
`lockdown()` has frozen JavaScript intrinsics and objects to prevent prototype pollution and tampering with the global environment.
fix
Do not attempt to modify built-in objects or their prototypes after `lockdown()` has been called. If you need to introduce polyfills or shims, they must be applied *before* `lockdown()`.
ReferenceError: fetch is not defined (or 'document is not defined', 'process is not defined')
Code running inside a `Compartment` does not have access to ambient authority (global browser/Node.js APIs) by default, adhering to POLA.
fix
To grant access to specific host APIs, pass them explicitly into the `Compartment`'s `globals` option. For example: `new Compartment({ globals: { fetch: harden(globalThis.fetch) } })`. Ensure any granted capabilities are `harden()`ed.
Error: Code evaluation is forbidden for `new Function(...)` (or `eval(...)`) after the compartment is locked down.
`lockdown()` replaces the global `Function` constructor and `eval` with versions that throw errors when used to evaluate source code directly, as a security measure.
fix
Use the `Compartment.prototype.evaluate(code)` method to securely run code within a specific `Compartment`'s scope. For dynamic module loading, explore `Compartment.prototype.import()` or `Compartment`'s `moduleMapHook`.
Upgrade
Version history
2.0.0latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
20 hits · last 30 days
node
16
OpenAI (training)
1
Resources