
OVHcloud CLI Compromised via GitHub Release Swap: Detonating the Real GlassWorm Loader and What We Found
Analysis of the 19 October 2026 swap of binaries on five ovh/ovhcloud-cli GitHub releases (v0.11.0 to v0.15.0), live 94 minutes. StepSecurity rebuilt the attacker's binary, detonated the recovered GlassWorm preinstall.js loader against a controlled Solana dead drop, and found install.sh never exposed arm64 Linux, Homebrew was safe, and `ovhcloud version` showing "undefined" identifies the swapped build. Includes IOCs and recovery steps.
What it is
On 19 October 2026, between 12:47 and 14:21 UTC (94 minutes), an attacker using the GitHub account HassenBF replaced the binaries on five releases of ovh/ovhcloud-cli (v0.11.0 to v0.15.0) with a credential stealer. The assets were downloaded about 250 times. No tag moved, no CI ran and the source was untouched. The attacker uploaded locally built binaries over existing releases and replaced checksums.txt last, so the published hashes matched. OVHcloud shipped a clean, immutable, attested v0.16.0 and published advisory GHSA-862f-55f5-vmvw. StepSecurity rebuilt the attacker's binary from commit 5ead8ef and replayed the install in an isolated chamber.
How it works
GitHub release immutability was not enabled, so any account with write access could swap assets at unchanged URLs. The binary was built locally from main commit 5ead8ef (13 October 2026) with -ldflags="-s -w" and without GoReleaser's -X .../internal/version.Version flag. The reporter's go version -m showed pseudo-version v0.15.1-0.20261013083505-5ead8ef9b43d+dirty. A rebuild shows vcs.modified=false instead of +dirty, so the pseudo-version and the missing version flag are the reliable markers.
In the replay, install.sh fetched the latest release with no checksum check. The stealer read 18 secret paths, staged a tar.gz in /tmp/envchecker-XXXX/ and POSTed it to https://45.32.148.174/upload as Solana-RPC-shaped JSON. Exfiltration finished 4 seconds after install began. Every later run stole again.
Access traces to a malicious VS Code extension (color-picker-universal 2.8.91) installed on the contributor's personal MacBook on 20 October 2025, and the release uploads used stolen keys. In March 2026 the account force-pushed hidden preinstall.js loaders to four personal repos. StepSecurity recovered one from orphaned commit 227207ce and detonated it. It is 181 bytes of visible JavaScript plus invisible variation-selector characters that decode to an AES-256-CBC wrapper. It skips Russian locales, polls nine public Solana RPC providers for a wallet memo carrying a base64 URL, fetches stage 3 and runs it in a Node vm with require exposed. The dead drop is empty now, consistent with the CrowdStrike-coordinated takedown of 26 May 2026, but the operator can re-arm it with a new memo.
flowchart TD
A[Swapped binary installed] --> B{Install path}
B -->|install.sh, x86_64 Linux, macOS, Windows| X[Exposed]
B -->|install.sh, arm64 Linux| N[404, not exposed]
B -->|ovhcloud upgrade or manual download, arm64| X
B -->|Homebrew cask| H[Pinned SHA-256 mismatch, refused]
B -->|go install, source, Docker| S[Not exposed]Preconditions / Affected
Exposed: anyone who downloaded or ran an ovhcloud binary from GitHub releases in the window, via install.sh or direct download on macOS, Linux x86_64 or Windows x86_64. CI jobs that fetched releases/download/v0.1[1-5].0/* in the window are also exposed, along with credentials reachable from those runners.
Corrections to earlier coverage, per StepSecurity:
- install.sh never served arm64 Linux. It builds the name from
uname -m(aarch64), but the asset is Linux_arm64, so it always 404'd. Arm64 users were exposed only throughovhcloud upgradeor a manual download. - Homebrew was safe. The cask pins per-arch SHA-256, so the swapped files were refused. OpenSourceMalware and Help Net Security listed it as an infection path.
What to do
Check for the swapped build:
ovhcloud version # "undefined" + commit 5ead8ef... = malicious
go version -m $(which ovhcloud) | head -5
ls -d /tmp/envchecker-* # stealer staging dirsovhcloud upgrade also refuses on the swapped build with "upgrade is not available in development builds."
If affected, treat the host as fully compromised and rotate from a different machine: OVH API keys, cloud keys, kubeconfigs, registry credentials, npm tokens, SSH keys, .netrc, git credentials, and AI-agent stores (Claude, Cursor, VS Code, Continue, Cody, OpenCode). Revoke PATs and tokens used since 19 October. Delete the binary and /tmp/envchecker-* directories, then reinstall v0.16.0 and verify:
gh release verify-asset v0.16.0 ovhcloud-cli_Linux_x86_64.tar.gzIf you cannot establish the machine is clean, rebuild it. Pin release hashes externally: the reporter caught the swap only because their CI pinned the Linux arm64 tarball SHA-256, while the repo's own checksums.txt had been swapped to match.
Blocking Solana RPC egress makes the loader crash with an unhandled atob InvalidCharacterError, which is visible in Node logs.
Caveats
The real binaries were deleted, so the replay uses a rebuild with a collection routine written to match the advisory's target list. The Linux arm64 malicious archive SHA-256 (from issue #300) is the only malicious archive hash published. Other platforms' swapped archives were probably never hashed, and public sources list binary MD5s instead. The page's IOC tables were not in the fetched text, so hashes, wallet and domains must come from the original post or the advisory.
Organisations named here
- color-picker-universal
- envchecker
- GHSA-862f-55f5-vmvw
- Ivan Kwiatkowski
- release asset swap
- Solana dead drop
- variation-selector steganography
Technologies named here
- OVHcloud CLI
- StepSecurity Harden-Runner
- StepSecurity Dev Machine Guard
- install.sh for ovhcloud-cli
- StepSecurity AI Package Analyst
- StepSecurity Threat Center
- Clean replacement
- gh release verify-asset
- go version -m
- ovhcloud version
- Blast-chamber replay
- Pinned SHA-256 in CI
- GitHub
- Solana
- Go
- Homebrew
- Node.js
- CrowdStrike
Techniques named here
- Solana blockchain dead-drop C2
Threat actors named here
- GlassWorm
Also named here
- ForceMemo
- HassenBF
Related in Supply Chain


