GlassWorm
The string assigned to _p looks empty, but it holds 38 Unicode variation selectors, characters that render as nothing. The decoder maps each one back to a byte and new Function runs the result. The GlassWorm campaign, found in VS Code extensions on Open VSX in October 2025, hid its loader this way. This proof of concept decodes to a harmless console.log. disclude flags the run of selectors as critical and decodes it, and separately flags the dynamic execution.
- Credit
- Technique of the GlassWorm campaign, reported by Koi Security (2025)
- File
glassworm.js(download)- Signals
- 2 critical · 0 warn · 0 info
- Disclude version
- 4.3.0
Source
Hidden characters are shown as ⟨U+…⟩. Each signal below links to its line.
// [!] EDUCATIONAL POC -- DO NOT USE MALICIOUSLY// This file appears to contain an empty string, but it holds an invisible payload.// Use a hex editor or the glassworm-detector to reveal the hidden content.const ;// The string below looks empty but contains 38 encoded bytes:const _p = `⟨U+E0153⟩⟨U+E015F⟩⟨U+E015E⟩⟨U+E0163⟩⟨U+E015F⟩⟨U+E015C⟩⟨U+E0155⟩⟨U+E011E⟩⟨U+E015C⟩⟨U+E015F⟩⟨U+E0157⟩⟨U+E0118⟩⟨U+E0117⟩⟨U+E0158⟩⟨U+E0159⟩⟨U+E0154⟩⟨U+E0154⟩⟨U+E0155⟩⟨U+E015E⟩⟨U+E0110⟩⟨U+E0160⟩⟨U+E0151⟩⟨U+E0169⟩⟨U+E015C⟩⟨U+E015F⟩⟨U+E0151⟩⟨U+E0154⟩⟨U+E0110⟩⟨U+E0155⟩⟨U+E0168⟩⟨U+E0155⟩⟨U+E0153⟩⟨U+E0165⟩⟨U+E0164⟩⟨U+E0155⟩⟨U+E0154⟩⟨U+E0117⟩⟨U+E0119⟩`;;
Signals
Ordered by severity.
-
// The string below looks empty but contains 38 encoded bytes: const _p = `⟨U+E0153⟩⟨U+E015F⟩⟨U+E015E⟩⟨U+E0163⟩⟨U+E015F⟩⟨U+E015C⟩⟨U+E0155⟩⟨U+E011E⟩⟨U+E015C⟩⟨U+E015F⟩⟨U+E0157⟩⟨U+E0118⟩⟨U+E0117⟩⟨U+E0158⟩⟨U+E0159⟩⟨U+E0154⟩⟨U+E0154⟩⟨U+E0155⟩⟨U+E015E⟩⟨U+E0110⟩⟨U+E0160⟩⟨U+E0151⟩⟨U+E0169⟩⟨U+E015C⟩⟨U+E015F⟩⟨U+E0151⟩⟨U+E0154⟩⟨U+E0110⟩⟨U+E0155⟩⟨U+E0168⟩⟨U+E0155⟩⟨U+E0153⟩⟨U+E0165⟩⟨U+E0164⟩⟨U+E0155⟩⟨U+E0154⟩⟨U+E0117⟩⟨U+E0119⟩`; ; -
;
Reproduce
Download the file and scan it. Copying it from this page won't work: the hidden characters are shown as markers.