ForumsGeneralWeaponizing Extension Packs: GlassWorm's New Vector in Open VSX

Weaponizing Extension Packs: GlassWorm's New Vector in Open VSX

BackupBoss_Greg 3/14/2026 USER

Just came across the latest update on the GlassWorm campaign, and it’s a textbook example of how supply chain attacks are evolving. We’re seeing 72 malicious extensions on the Open VSX registry, but the real kicker is the propagation method.

Instead of stuffing the payload into every single malicious extension, the actors are abusing extensionPack and extensionDependencies. They compromise a seemingly benign "utility" extension, which then silently pulls in a malicious dependency. This turns the dependency tree into a delivery system. For SOC analysts, this is a nightmare because the initial install might look perfectly clean on the surface.

I’ve started auditing our dev environments, specifically checking for these transitive dependencies. If you’re doing code review or dynamic analysis, make sure you aren’t just looking at the root package..

Here’s a quick Python script I whipped up to recursively scan a downloaded .vsix file for suspicious dependency chains before installation:

import 
import zipfile
import sys

def scan_vsix_dependencies(vsix_path):
    print(f"Scanning {vsix_path}...")
    try:
        with zipfile.ZipFile(vsix_path, 'r') as z:
            # VSIX files usually contain package. at root or in extension folder
            for filename in z.namelist():
                if 'package.' in filename:
                    with z.open(filename) as f:
                        data = .load(f)
                        deps = data.get('extensionDependencies')
                        packs = data.get('extensionPack')
                        if deps or packs:
                            print(f"[!] Found transitive dependencies in {filename}:")
                            print(f"    Dependencies: {deps}")
                            print(f"    Extension Packs: {packs}")
    except Exception as e:
        print(f"Error reading file: {e}")

if __name__ == "__main__":
    if len(sys.argv) ")
    else:
        scan_vsix_dependencies(sys.argv[1])

This is definitely a "trust nothing" scenario. How is everyone else handling VS Code/VSX extension governance in your orgs? Are you sticking to the Microsoft Marketplace exclusively, or do you have a private registry set up?

NE
NetGuard_Mike3/14/2026

Solid script. On the SOC side, we're trying to catch this post-installation. We're monitoring for code.exe spawning unexpected child processes like PowerShell or CMD shortly after an extension install event.

We added a KQL rule to correlate process creation with extension installation logs:

DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName in~("code.exe", "Code.exe")
| where ProcessCommandLine contains "--install-extension"
| join kind=inner (DeviceProcessEvents
| where FileName in~("powershell.exe", "cmd.exe", "pwsh.exe")
| where ProcessCommandLine contains "--install-extension") on DeviceId, InitiatingProcessId


It's noisy if devs are automating installs, but it catches the callback attempts.
SC
SCADA_Guru_Ivan3/14/2026

We moved to a strict allowlist for extensions months ago. It causes some friction with the dev team, but we block direct access to the Open VSX registry at the network level.

If a developer needs an extension, they submit a ticket. We download the .vsix, scan it, and host it on an internal server or an Artifactory instance. This completely negates the risk of a dependency chain pulling a malicious update from the public internet later on.

MD
MDR_Analyst_Chris3/16/2026

For endpoint detection, we're auditing the local package. files directly. Since these attacks rely on extensionPack declarations, checking for unexpected dependencies in the installed folder is a reliable way to spot the chain. You can use this script to scan the default extension directory:

import os, 
path = os.path.expanduser("~/.vscode/extensions")
for root, dirs, files in os.walk(path):
    if "package." in files:
        with open(os.path.join(root, "package.")) as f:
            data = .load(f)
            if "extensionDependencies" in data or "extensionPack" in data:
                print(f"Found Pack: {data['name']} -> {data.get('extensionDependencies', data.get('extensionPack'))}")

Verified Access Required

To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.

Request Access

Thread Stats

Created3/14/2026
Last Active3/16/2026
Replies3
Views194