Skip to content

Back to the catalog

Glassworm Hacks OVH Clouds CLI tool
opensourcemalware.comwriteup

Glassworm Hacks OVH Clouds CLI tool

OVHcloud CLI (ovh/ovhcloud-cli) release assets for v0.11.0 to v0.15.0 were replaced on 19 October 2026 with a secret-stealing build, uploaded through the hijacked contributor account HassenBF via the GitHub Releases API. No CI ran and source was untouched. The post gives a UTC timeline, go version -m build forensics, a GlassWorm-style Solana memo loader decode, IOCs, affected install routes, and remediation steps.

TL;DR Analyzes how a GlassWorm-linked hijacked contributor account swapped OVHcloud CLI release binaries with a dirty local build, with IOCs and response steps.
Document

What it is

On 19 October 2026, between about 12:47 and 13:12 UTC, an attacker replaced the release binaries of ovh/ovhcloud-cli v0.11.0 to v0.15.0 with a secret-stealing build. The uploads came from the GitHub account HassenBF, a contributor to other OVH repositories, through the ordinary Releases API. OVHcloud deleted the files at 14:21 UTC, so the bad files were downloadable for about 94 minutes. A clean, immutable v0.16.0 followed.

How it works

No tag was pushed and no workflow ran. The Actions run list shows nothing between 16 October 14:38 UTC and the v0.16.0 tag push on 19 October 16:00 UTC. The page notes that repo admins can delete runs.

The malicious build was a plain go build on a workstation. Its build info is v0.15.1-0.20261013083505-5ead8ef9b43d+dirty with vcs.modified=true. A real release build uses -trimpath, which strips vcs.* data, and sets the version ldflag. Six assets were replaced per release: both macOS builds, Linux x86_64 and arm64, Windows x86_64, and checksums.txt. The i386, Windows arm64 and WASM builds were left alone.

The page says HassenBF was already compromised. On 5 and 6 March 2026, four of its personal repositories were amended and force-pushed with a preinstall.js loader, which uses invisible Unicode variation selectors and eval. Stage two reads a memo from Solana wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC to find the next payload URL. The wallet appears in public GlassWorm indicator lists.

Preconditions / Affected

You are affected if you installed or updated between 12:47 and 14:21 UTC on 19 October on macOS, Linux x86_64/arm64 or Windows x86_64 through any of these routes:

  • install.sh (it does not verify checksums.txt)
  • brew install --cask ovh/tap/ovhcloud-cli or brew upgrade
  • a direct download from GitHub Releases
  • a CI job or Dockerfile that fetches releases/download/ tarballs

You are not affected if you used go install, built from source, pulled the ovhcom/ovhcloud-cli Docker image, or installed before 12:47 UTC without updating.

What to do

Check any binary you still have:

go version -m ./ovhcloud
./ovhcloud version

A clean build has no vcs.* lines and no +dirty, and prints a tag such as v0.15.0. You can also compare the archive's sha256sum against the known hashes. For v0.15.0 ovhcloud-cli_Linux_arm64.tar.gz, the original is 5c2beb56e6d83a4b426565a1557791ef759316abcc4effb38dd627c90aeb80e0 and the malicious one is 3833daffcaaaab27e4e0e0833240ffcb1df8df648f4ec0bc4a75c176e28933cb.

If you ran it, treat every secret readable from that machine as exposed: OVHcloud API keys, ~/.ovh.conf, cloud credentials, SSH keys, .npmrc/.pypirc/.netrc tokens, Kubernetes configs and .env files. Rotate from a different machine, remove the binary, and install v0.16.0 or later. v0.16.0 ships an attestation that gh attestation verify can check.

Defender suggestions from the page:

  • Alert on force pushes to long-idle repositories (the Activity API gives server timestamps; an amend shares its parent with the old tip).
  • Review or block preinstall scripts.
  • Block Solana RPC traffic from build hosts.
  • Hunt for ~/init.json (the macOS throttle marker) and for preinstall.js with SHA-256 43df42fd79f6f81e530892b54634598770d6e496796a863c596e616bcb3fec70.

Caveats

OVHcloud deleted the payload before anyone archived it, so the author did not analyze it. What it reads and where it sends data is unknown. The 12:47 to 13:12 times come from the reporter's capture in issue #300. Only v0.15.0, and Linux arm64 plus checksums for v0.13.0 and v0.14.0, are confirmed. The other replaced assets are inferred from what remains on the release pages.

The link between the March compromise and the October replacement rests on the shared account, not on direct observation. How the credentials were taken is unknown, and so is whether the long-lived TAP_GITHUB_TOKEN was exposed. OVHcloud has promised a post-mortem.

Organisations named here

  • ForceMemo
  • HassenBF
  • immutable releases
  • Octave Klaba
  • OVHcloud
  • release asset replacement
  • Solana memo dead drop
  • variation selector obfuscation

Technologies named here

  • GitHub Releases API
  • GitHub repository activity API
  • go version -m
  • OVHcloud CLI install routes
  • Not replaced
  • ovhcloud version
  • sha256sum
  • gh attestation verify
  • HassenBF personal repositories with the preinstall.js loader
  • GoReleaser
  • preinstall.js loader
  • Solana RPC endpoints
  • GlassWorm indicator lists and scanners
  • GitHub
  • Go
  • Solana
  • Node.js
  • Homebrew

Techniques named here

  • Account hijacking
  • Invisible-character payload encoding
  • Locale and timezone check
  • Detection of the dirty build
  • Detection by pinned SHA-256 in downstream CI
  • Account Takeover

Threat actors named here

  • ForceMemo campaign
  • HassenBF
  • GlassWorm
  • PolinRider
  • GhostAction