pwneglyph logo
web javascript nodejs dynamic-import data-url rce

Deliver attacker JS through a data:text/javascript module specifier that comments out an appended suffix.

Dynamic import() from a data: URL in Node

import() accepts module specifiers beyond filesystem paths. If the application concatenates a suffix onto an attacker-controlled specifier, a data: URL can comment out the suffix and deliver attacker JS directly.

Why It Works

  • A data:text/javascript,...// specifier executes inline JS; the trailing // swallows the appended suffix.

Vulnerable Pattern

  • Node code doing import(userInput + "/index.js") or similar naive module-specifier concatenation.

Exploit Flow

  1. Verify which module-specifier schemes the runtime accepts.
  2. Craft a data:text/javascript,...// payload so the appended suffix is ignored as a comment.
  3. Keep the first-stage payload simple — usually file read or a process pivot.

Variations

  • node: imports from the injected module, dynamic import of builtins, or secondary fetches inside the module.

Common Blockers

  • Runtime flags restricting data: imports, specifier sanitization, or ESM configuration differences.

PoC Sketch

requested=data:text/javascript,import fs from "node:fs";console.log(fs.readFileSync("/flag","utf8"))//

Good Situations To Use It

  • A Node app concatenates a suffix onto an import() specifier.
  • data: imports aren't restricted.
  • You only need a simple first-stage payload.

Sources

  • fcsc2026/web/fcsc_aquarium