---
title: A tool you installed from GitHub releases was swapped for malware: scope, contain, rotate | ctxsec
url: https://ctxsec.com/playbooks/poisoned-release-asset-response
---

[← Playbooks](/playbooks)

# A tool you installed from GitHub releases was swapped for malware: scope, contain, rotate

For when a vendor says assets on its release pages were replaced (this week: OVHcloud CLI v0.11.0-v0.15.0, swapped Oct 19 12:47-14:21 UTC). Built from OVHcloud's statements, OpenSourceMalware's server-side timeline and GitHub's malware-advisory guidance.

For: Security lead, Developer / DevOps, SOC / threat hunter

[1. Fix the exposure window](#s1)[2. Find every machine that pulled it](#s2)[3. Contain](#s3)[4. Rotate from a clean machine](#s4)[5. Reinstall safely](#s5)[6. If you publish releases too](#s6)

1.

Step 1 of 6

__

### Fix the exposure window

Only installs or updates during the swap window got the bad file. Earlier copies are the originals.

   - Write down the vendor's window in UTC (OVHcloud: Oct 19 12:47-14:21 UTC; Klaba's times are Paris time)
   - List affected versions and platforms (OVHcloud: v0.11.0-v0.15.0; macOS x86_64/arm64, Linux x86_64/arm64, Windows x86_64)
   - Note which install paths skip hash checks (install.sh, the self-upgrade command, raw release downloads)

2.

Step 2 of 6

__

### Find every machine that pulled it

Laptops, CI runners and golden images all count.

   - Search EDR and proxy logs for downloads from github.com/<org>/<repo>/releases/download/ and objects.githubusercontent.com in the window
   - Grep CI logs and build caches for the tool's archive names and versions
   - Check package-manager logs (Homebrew, scoop, apt mirrors). Sources disagreed on whether the OVHcloud Homebrew cask was exposed, so verify rather than assume
   - Compare installed binary hashes with the vendor's clean hashes, if published, or with a fresh build from source

3.

Step 3 of 6

__

### Contain

GitHub's guidance for malware packages is to treat the host as fully compromised.

   - Isolate hits and remove the binary
   - Prefer a rebuild over cleanup for CI runners and admin workstations
   - Block the binary's hash and any C2 the vendor or researchers publish

4.

Step 4 of 6

__

### Rotate from a clean machine

The OVHcloud payload's job was to read secrets from disk.

   - Revoke cloud and API keys, SSH keys, kube configs, git tokens, password-manager sessions and browser sessions stored on the host
   - Rotate CI secrets the runner could read
   - Review provider audit logs for use of those credentials since the window

5.

Step 5 of 6

__

### Reinstall safely

Install the vendor's clean release and pin it.

   - Install the clean version (OVHcloud: v0.16.0, published as an immutable release)
   - Pin version + SHA-256 or verify attestations in CI; fail on mismatch
   - Avoid curl | sh installers that fetch 'latest' without a hash on build hosts

6.

Step 6 of 6

__

### If you publish releases too

The same gap exists in your own repos.

   - Turn on GitHub immutable releases
   - Publish only from CI with a bot identity; review who has write or maintain access
   - Enable private vulnerability reporting so users don't have to report in public issues

Original content by ctxsec. Printable checklist: use your browser's print view.
