OVHcloud CLI Releases Were Swapped for a Secret-Stealing Build for 94 Minutes
Attackers used a hijacked developer account to replace OVHcloud CLI v0.11.0 to v0.15.0 binaries on GitHub with a secret-stealing build on October 19. If you installed or updated in that window, rotate every secret on the machine and move to v0.16.0.
Attackers swapped the release binaries of five versions of OVHcloud's official command-line tool, ovhcloud, for a build designed to steal secrets from the machine it runs on. The tampered files sat on the project's GitHub release pages for about 94 minutes on October 19 before OVHcloud deleted them. Anyone who installed or updated the CLI on macOS, Linux or Windows from those release pages during that window should treat every secret on that machine as exposed.
OVHcloud CEO Octave Klaba announced on X that the compromised versions are v0.11.0, v0.12.0, v0.13.0, v0.14.0 and v0.15.0, that v0.10.0 and the new v0.16.0 are clean, and that the attacker "used the GitHub account of one of the developers and added a binary whose job is to retrieve secrets from the disk." He called the binary's quality poor "but it can go all the way," and told affected users to change all the secrets on their disk. This is a supply-chain compromise, not a software vulnerability, and no CVE has been assigned.
Timeline
OVHcloud's statements use Paris time (UTC+2). The UTC times below come from Klaba's posts, the public GitHub issue #300, and the server-side GitHub records analyzed by OpenSourceMalware.
| UTC (Oct 19) | Manila | Event |
|---|---|---|
| 12:47 | Oct 19, 8:47 PM | First swapped files land on v0.15.0 |
| 12:57 to 13:12 | 8:57 to 9:12 PM | Checksums and the other releases swapped |
| 13:50 | 9:50 PM | A user files issue #300 after a pinned hash fails in CI |
| 14:21 | 10:21 PM | OVHcloud deletes all swapped files |
| 16:52 | Oct 20, 12:52 AM | Klaba posts the alert on X |
| 17:16 | Oct 20, 1:16 AM | Clean, immutable v0.16.0 published |
| 20:29 | Oct 20, 4:29 AM | Klaba declares the incident closed |
The issue was caught by a user, not by OVHcloud. Their CI job pinned the SHA-256 of ovhcloud-cli_Linux_arm64.tar.gz from v0.15.0 and started failing. In the issue, they showed that the new file was a local, "dirty" Go build of a later commit, uploaded by the account HassenBF rather than by the release pipeline, and asked whether it was intentional. OVH maintainer Romain Beuque replied that all the binaries involved were deleted at 16:21 Paris time and then shipped v0.16.0, saying the release is immutable "so the assets attached to it can be trusted." OVHcloud has promised a detailed post-mortem "in the coming days."
How it happened
No source code changed. The attacker replaced files attached to releases that had been published months earlier, using an account that already had write access to the repository. In his follow-up post, Klaba said the CI/CD pipelines, including unit tests, functional tests and CVE detection, were not affected. The gap was that GitHub's release immutability option had not been turned on, so a user with the right permissions could modify existing releases directly on GitHub without passing through OVHcloud's CI/CD. OVHcloud has since enabled it.
According to OpenSourceMalware, only the mainstream builds were replaced: macOS on Apple silicon and Intel, Linux x86_64 and arm64, Windows x86_64, and each release's checksums.txt, so the published hashes matched the swapped files. The Linux and Windows i386 builds, the Windows arm64 build and the WebAssembly build were left alone. The issue reporter confirmed the swaps directly for v0.13.0 to v0.15.0; for v0.11.0 and v0.12.0, the researchers rely on OVHcloud's statement and the files left behind.
| Version | First published | Swapped Oct 19 |
|---|---|---|
| v0.10.0 | Mar 2, 2026 | No (clean) |
| v0.11.0 | Apr 14, 2026 | Yes, per OVHcloud |
| v0.12.0 | May 29, 2026 | Yes, per OVHcloud |
| v0.13.0 | Aug 25, 2026 | Yes, confirmed in #300 |
| v0.14.0 | Aug 31, 2026 | Yes, confirmed in #300 |
| v0.15.0 | Sep 16, 2026 | Yes, confirmed in #300 |
| v0.16.0 | Oct 19, 2026 | No (clean, immutable) |
OpenSourceMalware also found that the HassenBF account, which belongs to a real OVH contributor, appears to have been compromised since at least March 5, 2026, when four of its personal repositories were force-pushed with a hidden JavaScript loader. That loader fetches its next stage through a Solana wallet memo, and the wallet appears on public GlassWorm indicator lists. The researchers stress that linking the March activity to the October release swap is their inference, based on the shared account.
What the payload did
Very little is public. OVHcloud says the binary looks for secrets on disk, and Klaba said the company is still analyzing it. OVHcloud deleted the swapped files before anyone archived them, so OpenSourceMalware says it has not analyzed the payload, and neither OVHcloud nor the researchers have published which paths it reads, where it sends data, or any network indicators. The one known-bad file hash comes from the issue reporter's CI.
Indicators
- Swapped file: v0.15.0
ovhcloud-cli_Linux_arm64.tar.gz, SHA-2563833daffcaaaab27e4e0e0833240ffcb1df8df648f4ec0bc4a75c176e28933cb(the original was5c2beb56e6d83a4b426565a1557791ef759316abcc4effb38dd627c90aeb80e0) - Build metadata of the swapped binary: module version
v0.15.1-0.20261013083505-5ead8ef9b43d+dirty,vcs.revision=5ead8ef9b43d354dfb5caadff803b11afc8c5c58,vcs.modified=true - Uploader: GitHub account
HassenBF - Related loader, per OpenSourceMalware:
preinstall.js, SHA-25643df42fd79f6f81e530892b54634598770d6e496796a863c596e616bcb3fec70; Solana walletBjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC; marker file~/init.jsonon macOS
Are you affected?
OpenSourceMalware says you are affected if, between 12:47 and 14:21 UTC on October 19 (8:47 to 10:21 PM Manila), you installed or updated the CLI on macOS, Linux x86_64 or arm64, or Windows x86_64 using the official install.sh script, a direct download from the releases page, or a CI job or Dockerfile that fetches from github.com/ovh/ovhcloud-cli/releases/download/. You are not affected if you used go install, built from source, used the ovhcom/ovhcloud-cli Docker image, or did not install or update during the window.
The researchers also list Homebrew as an affected route. However, the Homebrew cask that OVHcloud published for v0.15.0 pins the SHA-256 of the original archives, and Homebrew checks downloads against it, so a Homebrew install during the window should have failed with a checksum mismatch rather than installing the swapped file. OVHcloud has not addressed this, so Homebrew users who installed or upgraded during the window should still check.
Find the binary and when it was installed. Look for a timestamp inside the window. On Linux:
bin=$(command -v ovhcloud)
ls -lL --time-style=full-iso "$bin"On macOS, use stat -L -f '%Sm' "$(command -v ovhcloud)".
Inspect it without running it. If Go is installed, read the build info:
go version -m "$(command -v ovhcloud)" | grep -E 'mod|vcs'A line reading vcs.modified=true or a module version ending in +dirty marks the swapped build. OpenSourceMalware also notes that ovhcloud version prints the tag on clean builds but not on the swapped one; be aware that this command runs the binary.
Homebrew users: check the installed version and when it was installed:
brew list --cask --versions ovhcloud-cli
ls -l "$(brew --caskroom)/ovhcloud-cli"- Check any archive you kept. Run
sha256sumon it (shasum -a 256on macOS) and compare with the hashes above or with the checksums in the v0.16.0 release. - If you ran a swapped binary, rotate everything from a different, clean machine. OVHcloud's advice is to change all the secrets on your disk. OpenSourceMalware's list includes OVHcloud API application keys and consumer keys (including
~/.ovh.conf), other cloud provider credentials, SSH keys,.npmrc,.pypircand.netrctokens, Kubernetes configs and anything in.envfiles. Revoke the old OVHcloud API credentials rather than only issuing new ones, and include CI runners that fetched the CLI during the window.
Remove the binary and install v0.16.0 or later.
brew update && brew upgrade --cask ovh/tap/ovhcloud-cli
# or, without Homebrew:
u=https://raw.githubusercontent.com/ovh/ovhcloud-cli
curl -fsSL "$u/main/install.sh" | shThe v0.16.0 release ships a GitHub release attestation. With the GitHub CLI, you can check a downloaded archive using gh attestation verify ovhcloud-cli_Linux_x86_64.tar.gz --repo ovh/ovhcloud-cli.
The issue reporter's habit is the broader lesson: pinning and checking the hash of every third-party binary in CI is what flagged the swap about an hour after it began, and the files were deleted 94 minutes after the first one went up. Projects that publish binaries on GitHub can close the same gap by turning on immutable releases, as OVHcloud has now done.