StepSecurity Analyzes Malicious Immobiliare Labs Backstage npm Packages

Summary
StepSecurity reports that compromised releases of four Immobiliare Labs Backstage npm plugins used a binding.gyp/node-gyp install hook to run a payload targeting credentials and AI coding-assistant configurations. Full analysis is ongoing.
Key points
- StepSecurity identified compromised versions of four Immobiliare Labs Backstage plugins: the GitLab and LDAP authentication packages and their backend variants.
- Static analysis of @immobiliarelabs/backstage-plugin-gitlab 2.1.2 found a 5 MB index.js and a new binding.gyp file, both absent from the compared clean 2.1.1 release.
- The binding.gyp hook uses node-gyp to execute the payload during installation, bypassing tools that monitor only package.json postinstall scripts.
- The payload uses multiple obfuscation and encryption layers, downloads the Bun runtime, and runs a decrypted credential-harvesting payload. StepSecurity says Bun avoids a Node.js --require interception technique used by some monitoring tools.
- The analyzed payload targets GitHub, cloud-provider, Kubernetes, Vault, and package-registry credentials, among other sources; the article does not establish that credentials were successfully stolen.
- The payload also attempts to modify configuration for AI coding assistants to run code on session start or folder open.
- Functions in the payload suggest potential propagation through stolen npm and PyPI credentials. StepSecurity reported its findings to Immobiliare Labs; full payload analysis is ongoing.
Article Details
- Attack Vectors
- Compromised releases of four @immobiliarelabs Backstage plugins were published to npm; their binding.gyp files caused node-gyp to execute index.js during package installation.
- The payload used multiple obfuscation and encryption layers, downloaded the Bun runtime, and ran the decrypted credential-harvesting payload with Bun.
- The payload targeted credentials and secrets from GitHub Actions, cloud services, Kubernetes, HashiCorp Vault, package registries, password managers, and SSH key files.
- A function named infectHost modified AI coding assistant configuration files to add or trigger code execution on session start or folder open.
- Functions in the payload suggest it could use stolen npm and PyPI tokens to publish modified packages; the article describes this as a potential self-propagating supply-chain capability.
- Defensive Notes
- Check package manifests, lockfiles, CI workflows, and developer machines for the affected package versions listed in the article.
- Review systems that installed affected versions for the package-root index.js and binding.gyp files, unexpected node-gyp execution, Bun downloads, and modifications to AI assistant configuration files.
- Assess and rotate credentials accessible to affected install environments, including CI secrets, cloud credentials, registry tokens, password-manager data, and SSH keys.
- The article recommends monitoring CI runner network events, process execution, file access, and memory access; it says Harden-Runner can detect the node-gyp-to-curl/unzip/Bun process chain and unauthorized memory reads.
- The article describes package cooldown policies and checks against a database of compromised packages as measures that can delay or block newly published malicious versions.
MITRE ATT&CK
T1003.007 · Proc FilesystemThe payload attempted to read /proc/<pid>/mem for GitHub Actions masked secrets in the Runner.Worker process.T1005 · Data from Local SystemThe payload targeted credentials and secrets from local files, environment variables, process memory, and configuration sources.T1027 · Obfuscated Files or InformationThe payload used ROT-2, AES-128-GCM ciphertexts, obfuscator.io string-table rotation, and additional string encryption.T1059.004 · Unix ShellThe binding.gyp target used node-gyp shell expansion to invoke node index.js during installation.T1059.007 · JavaScriptThe package's binding.gyp hook ran index.js, and the payload executed decrypted JavaScript using Bun.T1074.001 · Local Data StagingThe wrapper wrote the decrypted main payload to a randomly named temporary file, executed it with Bun, and deleted the file.T1105 · Ingress Tool TransferThe payload downloaded the Bun runtime from a GitHub releases endpoint before executing its decrypted payload.T1195.002 · Compromise Software Supply ChainMalicious versions of four Immobiliare Labs Backstage plugins were published to npm and executed during installation.T1528 · Steal Application Access TokenThe payload targeted application and service tokens, including GitHub tokens and package-registry credentials.T1546 · Event Triggered ExecutionThe payload modified AI coding assistant configuration files to execute code on session-start or folder-open events.T1552.001 · Credentials In FilesCredential targets included token files such as Vault token paths and Kubernetes service-account tokens.T1552.004 · Private KeysThe payload targeted SSH keys in .ssh/.T1552.005 · Cloud Instance Metadata APIThe payload targeted AWS credentials through instance and ECS task metadata endpoints.T1555.005 · Password ManagersThe payload targeted password-manager databases associated with Bitwarden, 1Password, and gopass.
Products
@immobiliarelabs/backstage-plugin-gitlabfires at npm install time via a binding.gyp node-gyp hook. The affected packages are @immobiliarelabs/backstage-plugin-gitlab, @immobiliarelabs/backstage-plugin-gitlab-backend,@immobiliarelabs/backstage-plugin-gitlab-backendnode-gyp hook. The affected packages are @immobiliarelabs/backstage-plugin-gitlab, @immobiliarelabs/backstage-plugin-gitlab-backend, @immobiliarelabs/backstage-plugin-ldap-auth, and@immobiliarelabs/backstage-plugin-ldap-auth@immobiliarelabs/backstage-plugin-gitlab-backend, @immobiliarelabs/backstage-plugin-ldap-auth, and @immobiliarelabs/backstage-plugin-ldap-auth-backend. The payload steals@immobiliarelabs/backstage-plugin-ldap-auth-backend@immobiliarelabs/backstage-plugin-ldap-auth, and @immobiliarelabs/backstage-plugin-ldap-auth-backend. The payload steals credentials from a broad range of sources including GitHubAiderAider: modifies .aider.conf.ymlBackstagefires at npm install time via a binding.gyp node-gyp hook. The affected packages are @immobiliarelabs/backstage-plugin-gitlab, @immobiliarelabs/backstage-plugin-gitlab-backend,Bunevery supported release series. For a deep technical walkthrough of the binding.gyp execution technique, Bun-based evasion, and the worm propagation mechanism, see our detailed analysis of the Miasma campaign.Claude CodeClaude Code: writes to .claude/settings.json using the SessionStart hook to execute code on every session startCursorCursor: writes to .cursor/rules/GitHub ActionsThe payload steals credentials from a broad range of sources including GitHub Actions secrets, cloud provider credentials, and package registry tokens, and it attempts to persist insideGitHub CopilotGitHub Copilot: modifies .github/copilot-instructions.mdnpmOn June 26, 2026, multiple versions across several npm packages maintained by Immobiliare Labs were found to carry a malicious payload that fires at npm install time via a binding.gyp node-gyp hook. The affectedVS CodeVS Code: injects into .vscode/tasks.json using the folderOpen trigger
