Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
CRITICAL severity

CVE-2023-39532 ses

CRITICALFix: endojs/endo@fc90c64

CVE-2023-39532 is a critical-severity (CVSS 9.8) Improper Input Validation vulnerability in ses. 1 public exploit reference exists, so weaponization risk is real. A fix is available for ses — see the affected versions and patch details below.

SES's dynamic import and spread operator provides possible path to arbitrary exfiltration and execution

Also known asGHSA-9c4h-3f7h-322r
Published
Aug 8, 2023
Updated
Aug 12, 2026
Affected
6 pkgs
Patched
6 / 6
Exploits
1 known
Exploitation data as of Sep 19, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2023-39532.

EPSS Exploitation Probability

via FIRST.org ↗
1.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs70th percentile — riskier than 70% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

CVE-2023-39532 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,333 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

6 pkgs affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

118other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
sesnpm
194Kdownloads / week

Description

Impact

This is a hole in the confinement of guest applications under SES that may manifest as either the ability to exfiltrate information or execute arbitrary code depending on the configuration and implementation of the surrounding host.

Guest program running inside a Compartment with as few as no endowments can gain access to the surrounding host’s dynamic import by using dynamic import after the spread operator, like {...import(arbitraryModuleSpecifier)}.

On the web or in web extensions, a Content-Security-Policy following ordinary best practices likely mitigates both the risk of exfiltration and execution of arbitrary code, at least limiting the modules that the attacker can import to those that are already part of the application. However, without a Content-Security-Policy, dynamic import can be used to issue HTTP requests for either communication through the URL or for the execution of code reachable from that origin.

Within an XS worker, an attacker can use the host’s module system to the extent that the host has been configured. This typically only allows access to module code on the host’s file system and is of limited use to an attacker.

Within Node.js, the attacker gains access to Node.js’s module system. Importing the powerful builtins is not useful except insofar as there are side-effects and tempered because dynamic import returns a promise. Spreading a promise into an object renders the promises useless. However, Node.js allows importing data URLs, so this is a clear path to arbitrary execution.

Patches

All affected 0.* version trains have the following patch. Running npm update will obtain the patch on all affected projects using ^0.* style dependency constraints in their package.json.

From 33469e88bfb2bf34a161c265f10f808ce354a700 Mon Sep 17 00:00:00 2001
From: Kris Kowal <[email protected]>
Date: Thu, 27 Jul 2023 13:25:13 -0700
Subject: [PATCH] fix(fix): Censor spread import

---
 packages/ses/src/transforms.js       |  2 +-
 packages/ses/test/test-transforms.js | 22 +++++++++++++++++++++-
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/packages/ses/src/transforms.js b/packages/ses/src/transforms.js
index a0fc8d0ef..64a46cb53 100644
--- a/packages/ses/src/transforms.js
+++ b/packages/ses/src/transforms.js
@@ -106,7 +106,7 @@ export const evadeHtmlCommentTest = src => {
 // /////////////////////////////////////////////////////////////////////////////
 
 const importPattern = new FERAL_REG_EXP(
-  '(^|[^.])\\bimport(\\s*(?:\\(|/[/*]))',
+  '(^|[^.]|\\.\\.\\.)\\bimport(\\s*(?:\\(|/[/*]))',
   'g',
 );
 
diff --git a/packages/ses/test/test-transforms.js b/packages/ses/test/test-transforms.js
index cef0c02c1..8f6818b83 100644
--- a/packages/ses/test/test-transforms.js
+++ b/packages/ses/test/test-transforms.js
@@ -6,7 +6,7 @@ import {
 } from '../src/transforms.js';
 
 test('no-import-expression regexp', t => {
-  t.plan(9);
+  t.plan(13);
 
   // Note: we cannot define these as regular functions (and then stringify)
   // because the 'esm' module loader that we use for running the tests (i.e.
@@ -20,6 +20,7 @@ test('no-import-expression regexp', t => {
   const safe = 'const a = 1';
   const safe2 = "const a = notimport('evil')";
   const safe3 = "const a = importnot('evil')";
+  const safe4 = "const a = compartment.import('name')";
 
   const obvious = "const a = import('evil')";
   const whitespace = "const a = import ('evil')";
@@ -27,10 +28,14 @@ test('no-import-expression regexp', t => {
   const doubleSlashComment = "const a = import // hah\n('evil')";
   const newline = "const a = import\n('evil')";
   const multiline = "\nimport('a')\nimport('b')";
+  const spread = "{...import('exfil')}";
+  const spread2 = "{\n...\nimport\n('exfil')}";
+  const spread3 = "{\n...\nimport/**/\n('exfil')}";
 
   t.is(rejectImportExpressions(safe), safe, 'safe');
   t.is(rejectImportExpressions(safe2), safe2, 'safe2');
   t.is(rejectImportExpressions(safe3), safe3, 'safe3');
+  t.is(rejectImportExpressions(safe4), safe4, 'safe4');
   t.throws(
     () => rejectImportExpressions(obvious),
     { instanceOf: SyntaxError },
@@ -62,6 +67,21 @@ test('no-import-expression regexp', t => {
     'possible import expression rejected around line 2',
     'multiline',
   );
+  t.throws(
+    () => rejectImportExpressions(spread),
+    { instanceOf: SyntaxError },
+    'spread',
+  );
+  t.throws(
+    () => rejectImportExpressions(spread2),
+    { instanceOf: SyntaxError },
+    'spread2',
+  );
+  t.throws(
+    () => rejectImportExpressions(spread3),
+    { instanceOf: SyntaxError },
+    'spread3',
+  );
 });
 
 test('no-html-comment-expression regexp', t => {
-- 
2.40.1

Workarounds

On the web, providing a suitably constrained Content-Security-Policy mitigates most of the threat.

With XS, building a binary that lacks the ability to load modules at runtime mitigates the entirety of the threat. That will look like an implementation of fxFindModule in a file like xsPlatform.c that calls fxRejectModuleFile.

We highly advise applying the above patch for Node.js as there is no known work-around and Node.js’s module specifiers are exceedingly powerful, including support for data:text/javascript, style module specifier URLs.

References

No references at this time.

Affected Packages

6 total 6 fixed
EcosystemPackageVulnerable rangeFix
📦npmses0.13.0&&< 0.13.50.13.5npm install ses@0.13.5
📦npmses0.14.0&&< 0.14.50.14.5npm install ses@0.14.5
📦npmses0.15.0&&< 0.15.240.15.24npm install ses@0.15.24
📦npmses0.16.0&&< 0.16.10.16.1npm install ses@0.16.1
📦npmses0.17.0&&< 0.17.10.17.1npm install ses@0.17.1
📦npmses0.18.0&&< 0.18.70.18.7npm install ses@0.18.7
Exploits & PoCs
1

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for ses, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update ses to 0.13.5 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2023-39532 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2023-39532 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2023-39532. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Impact This is a hole in the confinement of guest applications under SES that may manifest as either the ability to exfiltrate information or execute arbitrary code depending on the configuration and implementation of the surrounding host. Guest program running inside a Compartment with as few as no endowments can gain access to the surrounding host’s dynamic import by using dynamic import after the spread operator, like `{...import(arbitraryModuleSpecifier)}`. On the web or in web extensions, a Content-Security-Policy following ordinary best practices likely mitigates both the risk of
O3 Security · Impact-Aware SCA

Is CVE-2023-39532 in your dependencies?

O3 Security finds CVE-2023-39532 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2023-39532: ses RCE (Critical 9.8) | O3 Security