Direct naar de inhoud
Software Supply Chain Security

Rust supply chain: build-time malware via crates

build-time malware

Een nieuwe supply chain aanval in de Rust-wereld draait om build-time malware: kwaadaardige code die niet wacht op runtime, maar al actief wordt zodra een project compileert. De Rust Security Response Team meldde dat drie bekende crates in een korte periode gemanipuleerde releases publiceerden, waarna het platform ze later weer verwijderde.

Het incident laat zien hoe één gecompromitteerd maintainer-account en een subtiele dependency-wijziging voldoende kunnen zijn om tijdens het build-proces een externe payload op te halen en uit te voeren. Hieronder lees je wat er gebeurde, hoe het werkte, welke signalen onderzoekers zagen en welke acties je kunt nemen.

Wat is er precies gebeurd op crates.io?

De Rust Project-organisatie heeft drie kwaadaardige versies van veelgebruikte Rust-crates verwijderd nadat een maintainer-account was gecompromitteerd. In die releases werd een typosquatted dependency toegevoegd: een package-naam die sterk lijkt op een bekende en daardoor makkelijker wordt geaccepteerd.

De getroffen versies waren:

  • arrayref 0.3.10
  • internment 0.8.7
  • append-only-vec 0.1.9

Allemaal werden ze vanuit hetzelfde owner-account gepubliceerd op 2026-08-20 en binnen grofweg 86 tot 107 minuten weer verwijderd. Dat relatief korte tijdsvenster maakt duidelijk hoe belangrijk snelle detectie en snelle uitrol van mitigaties is.

Waarom werd dit “build-time malware” genoemd?

Het gevaar zat niet in de reguliere crate-functionaliteit, maar in de build script van de geïnjecteerde dependency. Zodra een project die (sub)dependency oploste, werd het build script uitgevoerd. Cruciaal daarbij: er hoefde niets uit de gemanipuleerde crate te worden aangeroepen om de payload te laten draaien.

Onderzoekers stellen dat de build met alleen de aanwezigheid van de afhankelijkheid al genoeg was. Dat is precies waarom dit incident zo’n duidelijke case is van build-time malware: “compileren” werd de aanvalsmethode.

De aanvalstechniek: typosquat, proc-macro1 en TLS-uitval

Volgens de advisories kreeg elke gecompromitteerde release één regel toegevoegd in het manifest. Die wijziging voegde een afhankelijkheid toe naar proc-macro1, een typosquat van het veel gebruikte proc-macro2. De broncode van proc-macro1 zelf bleek een echte kopie van proc-macro2, waardoor de build er “normaal” uitzag.

De echte afwijking zat in het build script. Dat script reconstrueerde op build-tijd de host en het command-and-control adres uit base64-fragmenten. Daarna installeerde het een aangepaste certificate verifier waarbij de verificatiemethoden altijd succes teruggeven. Met andere woorden: TLS-validatie werd onderuit gehaald, zodat een verbinding met de C2 zonder echte certificaatcheck mogelijk werd.

Daarna koos de payload een van meerdere varianten op basis van besturingssysteem en CPU-architectuur.

Wat deed de payload op Windows, Linux en macOS?

De onderzoekers beschrijven een twee-fasen aanpak: een “stage-1” die tijdens build start en een “stage-2” die via het netwerk communiceert. De stage-2 beacons zouden HTTPS POST’s sturen naar een specifiek pad op de payload host.

Bestandspaden en uitvoering

Op Unix en macOS schreef de malware bytes naar /tmp/rust-setup, markeerde het bestand als uitvoerbaar en startte het proces losgekoppeld (detached). Op Windows werd een PowerShell script naar %TEMP%\rust-setup.ps1 weggeschreven, vervolgens gestart via een VBScript launcher onder wscript.exe, waarna de malware het kindproces verliet op een manier die moest voorkomen dat Cargo op het proces bleef wachten.

Welke doelen werden nagestreefd?

Wiz meldde dat het uiteindelijke gedrag browsergegevens kan misbruiken. Het zou credentials uit databases van Chrome, Brave en Edge halen door SQLite-loginbestanden te bevragen. Over detailniveau verschilde de analyse per platform: Nextron analyseerde vooral de Windows-stage en rapporteerde dat die variant alleen bepaalde kolommen opvroeg (zoals herkomst en gebruikersnaam), maar niet aantoonbaar direct wachtwoorden uitlas—met de kanttekening dat Linux en macOS niet volledig waren geanalyseerd.

Indicatoren van compromis (IoC’s)

StepSecurity deelde verschillende IoC’s die je kunt gebruiken om verdachte sporen te checken. Niet elk signaal betekent meteen compromittering, maar samen met andere context kan het helpen om risico’s snel in te schatten.

Netwerk

  • 23.254.165.112:9089 (payload host)
  • 23.254.165.112:443 (C2)
  • hwsrv-798836.hostwindsdns.com

Bestanden

  • /tmp/rust-setup
  • %TEMP%\rust-setup.ps1
  • %TEMP%\rust-setup-launch.vbs

Binaries en accountcontext

  • Binairepaden zoals rust-crate_0.1.0, _0.2.0, _0.3.0, _0.4.0
  • Accountverwijzingen: een illegitiem lijkend account dtolney (verondersteld impersonator) en het legitieme owner-account droundy dat als gecompromitteerd werd beschouwd

De gedeelde lijst bevatte ook een e-mailadres dat zou zijn gebruikt voor vervalste metadata: rchaitm@gmail.com.

Hoe verspreidde het zich via afhankelijkheidsketens?

De aanval werkte door de combinaties die Cargo toeliet. De belangrijkste nuance: veel projecten gebruiken caret-versioning (^0.3.x), en zo’n bereik pakt doorgaans updates binnen dezelfde “minor/patch”-range mee. Daardoor werd 0.3.10 mogelijk geaccepteerd, zelfs als een project afhankelijkheid op een lager maximum had gemodelleerd.

Onderzoekers verifieerden dat er afhankelijkheidsketens waren waarin de kwetsbare crate werd meegenomen. Voorbeeldketens die werden genoemd:

  • winit vereiste sctk-adwaita ^0.10.1
  • sctk-adwaita vereiste tiny-skia ^0.11
  • tiny-skia vereiste arrayref ^0.3.6

In caret-bereiken valt 0.3.10 binnen acceptatie. Met andere woorden: zelfs als je eigen directe dependency niet “met naam en versie” op de slechte release wees, kon de resolver toch bij het besmette pad uitkomen.

Is er een patch? En was er een CVE?

Er is geen gepatchte versie gemeld. Ook werd er geen CVE-identifier toegewezen. De RustSec advisories zouden bovendien aangeven dat er geen bewijs is dat de kwaadaardige versies daadwerkelijk werden gebruikt in de onderzochte context.

De remedie is daarom vooral preventief en proactief: verwijder de releases uit je dependency lockbestand waar relevant, en voorkom dat een build opnieuw een oude gemanipuleerde crate resolveert.

Wat kun je nu doen als je Rust projecten bouwt?

De aanbeveling van de Rust Security Response Team en de context uit de publicatie richt zich op het snel scannen en stabiliseren van je builds.

  • Zoek lokaal naar caches: controleer in je Cargo-registry-cache (zoals ~/.cargo/registry/cache) op verwijderde cratebestanden.
  • Pin of forceer versies: pin arrayref op 0.3.9 of eerder, zoals geadviseerd na het unyanken van de malafide releases.
  • Herbouw en verifieer: laat je CI/CD pipelines opnieuw draaien met bijgewerkte dependency-locking, zodat compilatie niet opnieuw naar de gemanipuleerde versies kan wijzen.
  • Let op build-fasen: denk niet alleen aan runtime-security. Controleer ook scripts en build hooks van dependencies, omdat juist daar de trigger zat.

Als je veel samenwerkt met derde partijen of cross-team build farms gebruikt, is het extra verstandig om build-artefacten en logs te bewaren. Dan kun je sneller bepalen of een verdachte build in het verleden plaatsvond.

Waarom dit incident extra aandacht verdient

Dit soort aanvallen staat niet op zichzelf. In dezelfde periode werd in andere ecosystemen ook supply chain misbruik gemeld, waarbij kwetsbaarheid niet in je eigen code zat, maar in de afhankelijkheden die je nodig had. Wat opvalt, is de “koelperiode” gedachte: beperken dat heel verse third-party assets meteen breed worden uitgerold.

Voor Cargo bestaat er geen directe shipped tegenhanger zoals bij npm’s cooling windows. Wel liep er een voorstel om een minimumleeftijd voor publicaties in te stellen, zodat dependencies die nog heel nieuw zijn minder snel (of pas later) worden meegenomen. In de beschreven tijdlijn stond zo’n wijziging nog open en was hij niet ingevoerd.

Dat maakt deze case een wake-up call: zonder governance in dependency selection kan één snelle publicatie voldoende zijn.

Conclusie: bouw veiliger tegen build-time malware

De Rust supply chain aanval toont hoe build-time malware via crates.io kan ontstaan: een gecompromitteerde maintainer voegt een typosquat dependency toe, en de payload draait tijdens compilatie via een gemanipuleerd build script. Doordat de versies snel zijn verwijderd, viel de werkelijke schade niet automatisch overal—maar het risico is reëel voor elke organisatie die regelmatig Rust builds draait met automatische dependency resolving.

Door caches te scannen, verdachte versies te pinnen en je builds te controleren op de build-fase van dependencies, verlaag je de kans dat je pipeline ooit opnieuw de verkeerde code binnenhaalt.

Wil je dit thema breder bekijken binnen security van software delivery? Lees dan ook AI modelbeveiliging met sandboxing: leer van CameraSwarm voor een vergelijkbare denkrichting over het beheersen van executie tijdens het proces.

Bron: https://thehackernews.com/2026/08/rust-supply-chain-attack-puts-build.html