TL;DR: A malicious RubyGems campaign used a fake git_credential_manager package and republished dormant gems to turn trusted dependency updates into developer-workstation compromise, with loaders that disabled TLS verification, fetched remote payloads, and attempted persistence, according to Corgea. Dormant package ownership is now an initial access path, and transitive library load must be treated as an execution boundary.
NHIMG editorial — based on content published by Corgea: analysis of the RubyGems sleeper compromise and persistent backdoor chain
Questions worth separating out
Q: What fails when a trusted package can execute code during normal library load?
A: The trust model fails because reviewers often inspect install scripts while ignoring code that runs as soon as a dependency is required.
Q: Why do dormant packages create supply-chain risk in developer environments?
A: Dormant packages are risky because attackers can exploit stale ownership, low monitoring, and existing trust in old dependency names.
Q: How do security teams know if a package compromise is actually contained?
A: They should confirm three things: the bad version no longer appears in lockfiles, SBOM records no longer resolve to it, and running services no longer load it.
Practitioner guidance
- Hunt for the affected versions and their republished dependencies Search lockfiles, bundle caches, and local gem inventories for git_credential_manager 2.8.0 through 2.8.3, Dendreo 1.1.3 and 1.1.4, and fastlane-plugin-run_tests_firebase_testlab 0.3.2.
- Inspect runtime-loading dependencies for downloader behaviour Review Ruby gems and plugins that execute code on require, disable TLS verification, or pull remote payloads during normal library load.
- Check developer endpoints for persistence artefacts Look for ~/.local/share/gcm/, user-level systemd units, cron entries, and unexpected binaries such as /usr/local/sbin/ping6 on Linux hosts.
What's in the full analysis
Corgea's full analysis covers the operational detail this post intentionally leaves for the source:
- Version-by-version package chronology showing how the malicious chain evolved across the affected RubyGem releases.
- Process-tree and persistence details from the Linux payload, including systemd user units, cron, and privilege-escalation attempts.
- Environment-variable checks used to evade CI execution and bias the malware toward developer workstations.
- Source excerpts and artefacts that help AppSec teams reproduce detection logic in package review pipelines.
👉 Read Corgea's analysis of the RubyGems sleeper compromise and developer workstation persistence →
RubyGems sleeper compromise and developer workstation persistence risks?
Explore further
Dormant package ownership is now a credential-adjacent attack surface. The compromise worked because trust in a package name, not just a login credential, was sufficient to get code running on developer machines. That expands the IAM threat model into software supply-chain governance, where maintainership, package reputation, and dependency provenance all need lifecycle controls. Practitioners should treat dormant packages as high-risk identity assets, not neutral code artifacts.
A few things that frame the scale:
- The average estimated time to remediate a leaked secret is 27 days, despite 75% of organisations expressing strong confidence in their secrets management capabilities, according to The State of Secrets in AppSec.
- Only 44% of developers are reported to follow security best practices for secrets management, exposing a significant developer behaviour gap.
A question worth separating out:
Q: Who should own response when a developer package exposes credentials?
A: Ownership should sit across application security, endpoint operations, and IAM because the blast radius spans code, host, and identity. AppSec can confirm the package path, endpoint teams can remove persistence, and IAM teams can revoke secrets and sessions. When secrets may have been exposed, the response is an identity incident as much as a software one.
👉 Read our full editorial: RubyGems sleeper compromise shows how dormant packages become initial access