On 19 October, an attacker using a hijacked contributor's GitHub account replaced the downloadable archives attached to five existing releases of the OVHcloud CLI with builds that steal secrets from the machine that runs them. The files were live for about 94 minutes, on macOS, Linux and Windows.

The clean release is v0.16.0, published as a signed tag and an immutable release so its files cannot be swapped.

The part that should change how you think about pinning

Most supply-chain defence assumes the attack arrives as a new version. You pin to a known-good release, you review what changes before you move, and the bad version is one you have not adopted yet.

That is not what happened here. The versions were already published, already downloaded, already pinned by people who had done the careful thing. What changed was the file sitting behind the tag.

So a build that pulled v0.14.0 on Saturday got one binary, and a build that pulled v0.14.0 inside that 94-minute window on Monday got a different one. Same version. Same URL. Different bytes.

This is the second time this week that a version number has failed to identify a file. We wrote this morning about a WordPress plugin where the clean build and the backdoored one were both 3.0.123. The mechanics differ. The consequence for anyone trying to answer "am I affected" is identical, and it is that the version string cannot answer it.

Why it was possible

OVHcloud's founder has said the immutability option on releases was not enabled, which meant a user with sufficient permissions could edit an existing release directly, from the web interface, without going anywhere near the build pipeline.

That is worth sitting with. The CI/CD pipeline was not compromised. Every control that signs, builds and tests was intact and irrelevant, because the artefact store allowed a human to replace the output afterwards.

Immutability has since been turned on, and v0.16.0 was published with it.

What the scale actually is

Only people who installed or updated the CLI during the window received a malicious build, which makes the population small and impossible for anybody outside OVHcloud to enumerate. There is no telemetry that tells you whether your CI job pulled the binary at 14:05 or 14:55.

The payload steals secrets stored on disk, which for a cloud provider's CLI means exactly the credentials you would expect that machine to hold. OVHcloud's advice is to update or delete the tool; Klaba's is blunter, and it is to change every secret stored on the affected machine.

OVHcloud's initial checks found no other affected repository. One analysis links the account used to a cluster associated with GlassWorm, but says so on the basis of shared account identity rather than observed behaviour, and reports finding none of that cluster's usual markers here.

What a pinned version actually guarantees

It is worth being precise about this, because "pin your dependencies" is advice everybody repeats and few people have examined.

Pinning a version guarantees that your tooling will ask for the same name. It guarantees nothing about what comes back, unless something in the chain binds that name to specific bytes. A lockfile with an integrity hash does that. A signed tag does that, if anybody checks the signature. A version number on its own does not, and a release page's attached files are mutable by default on the platform most of this industry publishes through.

Which is why the fix OVHcloud applied is the right one and is also an admission: the control that would have prevented this was a checkbox, available all along, switched off.

If you maintain anything people download, the question to ask this week is not whether your pipeline is secure. It is whether somebody with your permissions could replace a published artefact without the pipeline running at all.

What to do

  • If you installed or updated the OVHcloud CLI on 19 October, treat the machine as having leaked whatever secrets were on its disk, and rotate them. Not just OVHcloud credentials.
  • Check build logs for when your pipelines fetched the CLI, because that is the only way to know which side of the window you were on.
  • Move to v0.16.0, which is signed and immutable.
  • Turn on release immutability in your own repositories. The control exists, it is free, and the absence of it is what turned a stolen account into a supply-chain incident.
  • Where you can, verify artefacts by hash or signature rather than by version, and record the hash you accepted. A version string is a label; a digest is a fact.

What is not established

  • Which versions exactly. OVHcloud's founder describes v0.11.0 through v0.15.0; the public issue lists v0.13.0 to v0.15.0. Nobody has reconciled the two.
  • How the contributor's GitHub account was taken over.
  • How many people downloaded a malicious build.
  • The exact window. About 94 minutes is the figure in circulation and the publication timestamps for v0.16.0 differ between accounts by over an hour.
  • Who did it. The GlassWorm link is an account-identity observation, not an attribution.
  • Whether anything was done with the stolen secrets.