Kort samengevat: de HulkApps-checkoutkaping op Shopify
- Wat er gebeurde: vanaf 2026-10-10 werden shoppers in meerdere Shopify-winkels die op Checkout klikten naar een nagemaakte betaalpagina op biliing[.]top gestuurd, die hun kaartgegevens buitmaakte en hen daarna doorstuurde naar de echte checkout.
- Hoe het binnenkwam: het bestand van de app Hulk Product Options op cdn.shopify.com was schoon. De aanvalscode kwam terug van de configuratie-API van HulkApps in een veld voor aangepast JavaScript en werd tijdens runtime geïnjecteerd. Swym Wishlist Plus en Selleasy werden op dezelfde manier getroffen.
- Waarom het niet werd opgemerkt: het werd alleen actief bij een echte klik op Checkout, één keer per browsersessie, naar domeinen die geen enkele blokkeerlijst kende. Scanners, CSP en de meeste handmatige tests zagen een normale winkel.
Weinig tijd? Bekijk cside's client-side scriptmonitoring. Dit dekt alles hieronder in één deployment.
Op 2026-10-10 deed ontwikkelaar Roman Zipp boodschappen in een populaire Shopify-winkel. Hij legde een toetsenbord in zijn winkelwagen, klikte op Checkout en kwam uit op wat eruitzag als een normale Shopify-checkout. Het enige signaal: zijn wachtwoordmanager bood aan het veld "Voornaam" in te vullen met de naam op zijn creditcard. Hij keek naar de adresbalk: biliing[.]top/check-out/.
De bestelling zou gewoon zijn doorgegaan. Zodra de neppagina de kaartgegevens had, stuurde ze hem direct door naar de echte checkout van de winkel. De kaart zou gecompromitteerd zijn, en niets in de bestelgegevens van de webwinkel zou afwijkend hebben geleken.
De code zat niet in het thema van de winkel, en de checkout van Shopify zelf is nooit aangeraakt. Ze kwam binnen via Hulk Product Options, een veelgebruikte app voor productopties van HulkApps, als een blok "aangepast JavaScript" dat de API van de leverancier zelf teruggaf. Binnen enkele dagen meldden webwinkels die nooit een HulkApps-product hadden geïnstalleerd dezelfde nep-checkout, herleid tot apps van andere leveranciers. Dit is een client-side supply-chainaanval in zijn zuiverste vorm: een derde partij die webwinkels legitiem toegang hadden gegeven tot de browsers van hun klanten, werd het afleverkanaal.
Hoe de aanval werkte
Elke schakel in deze keten leek op zichzelf legitiem. Zipp volgde het stap voor stap in Chrome DevTools.
- Een vertrouwd bestand laadt. Hulk Product Options levert een thema-extensie die
hulkcode.jsop winkelpagina's laadt. Het bestand komt vancdn.shopify.comals onderdeel van het extensiepakket. Het was niet aangepast. - Het bestand vraagt zijn configuratie op. Bij het laden van de pagina stuurt
hulkcode.jséén POST-verzoek naarproductoption.hulkapps.com/api/v2/store/get_all_relationshipsmet de winkel-ID en het bekeken product. - De configuratie bevat code. Het JSON-antwoord bevat een veld
advanced_users.custom_js, een functie waarmee webwinkels hun eigen JavaScript kunnen toevoegen. In getroffen winkels stond er ongeveer 22,7 KB niet-geminificeerde aanvalscode in. - De code wordt tijdens runtime geïnjecteerd. De app schrijft die tekst als script in de pagina. In DevTools verschijnt het als anoniem VM-script zonder bronbestand, wat het juist zo moeilijk te vinden maakt.
- De klik op Checkout wordt gekaapt. Het script registreert een klik-listener. Als de shopper op Checkout klikt, annuleert een functie die letterlijk
hijackheet de echte navigatie en leidt om naar een nagemaakte checkout op een domein van de aanvaller. - De nep-checkout verzamelt de kaart. De nagemaakte pagina imiteert een Shopify-checkout en vraagt om betaal- en persoonsgegevens.
- De gegevens vertrekken. Het formulier stuurt alles naar
/api/submissionsop het domein van de aanvaller, dat antwoordt met een record-ID. - De shopper wordt teruggestuurd. De neppagina stuurt de shopper door naar de echte Shopify-checkout, waar de bestelling normaal wordt afgerond. Het script zet ook
__ctf_shim_handoff_done_v1in de sessieopslag zodat het nooit twee keer in dezelfde sessie actief wordt.

Stap 1 en 2 zijn precies wat de app in elke winkel, elke dag doet. De hele aanval zat in de data die de API van de leverancier teruggaf.
De ontwerpkeuzes zijn bewust. Alleen omleiden bij de klik op Checkout zorgt dat gewone paginaladingen schoon lijken. Eén keer per sessie actief worden zorgt dat de webwinkel, de appleverancier en iedereen die een klacht van een klant onderzoekt meestal een normale checkout ziet bij het reproduceren. En omdat de gestolen bestelling op de echte checkout wordt afgerond, tonen omzetdashboards niets ongewoons.
Het was nooit alleen HulkApps
HulkApps was de eerste naam die aan deze campagne werd gekoppeld, maar daar houdt het verhaal niet op. Meerdere populaire apps van verschillende leveranciers leverden dezelfde omleiding naar dezelfde familie domeinen, en telkens zat de lading in configuratiegegevens die de app van de servers van de leverancier ophaalde.
| App | Leverancier | Wanneer | Wat er is gezegd |
|---|---|---|---|
| Selleasy | Logbase | 2026-10-13 | Logbase zegt dat een onbevoegde partij toegang kreeg tot een interne Selleasy-tool en een script toevoegde aan de instellingen van enkele winkels. Dezelfde dag verwijderd; Custom JS werd tijdelijk uitgeschakeld. |
| Swym Wishlist Plus | Swym | Gemeld op 2026-10-15 | Een ontwikkelaar herleidde de lading tot de configuratie van Swym, naar verluidt een kwaadaardig label op de verlanglijstknop. Een update rond 2026-10-14 lijkt die tekst te escapen. Geen openbare verklaring van Swym gevonden. |
| Hulk Product Options | HulkApps | 2026-10-10 | HulkApps zegt dat een exploit ongeautoriseerde configuraties in de thema-extensie van de app introduceerde, en dat zijn controle geen andere Hulk-apps vond die omleidingen uitvoerden. Shopify schakelde de extensie tijdelijk uit; HulkApps heeft een extern beveiligingsbedrijf ingeschakeld. |
| Hextom-apps | Hextom | Augustus 2026 | Door Zipp genoemd als eerder, opgelost incident. Geen openbare melding van de leverancier gevonden. |
| Sticky Add to Cart, Mega Menu | Qikify | 2026-07-22 | Qikify zegt dat code werd geïnjecteerd in HTML-velden in de appinstellingen. Dezelfde dag verholpen; de apps keerden op 2026-08-21 terug in de App Store. |
Het is verleidelijk dit als een inbraak bij één leverancier te zien. Het bewijs wijst op iets ongemakkelijkers: iemand die systematisch Shopify-apps afgaat waarmee configuratiegegevens uitvoerbare code in de winkel worden. Of dat via één gedeelde zwakte, gestolen inloggegevens of meerdere losse inbraken ging, is nog onbekend. Op 2026-10-16 stonden de App Store-pagina's van Hulk Product Options, Swym Wishlist Plus en Selleasy allemaal als niet beschikbaar, en een Australische webwinkelier vertelde iTnews dat Shopify haar had geadviseerd haar winkel gesloten te houden.
Waarom het langs de gebruikelijke verdediging glipte
De aanval was geen geavanceerde code. Het was een geavanceerde plek. Bijna elke controle waarop een webwinkel had kunnen vertrouwen, keek naar de verkeerde laag.
- Het scriptbestand veranderde nooit.
hulkcode.jskwam vancdn.shopify.commet dezelfde inhoud als altijd. Hashcontroles en Subresource Integrity zouden zijn geslaagd, omdat het kwaadaardige deel als data binnenkwam, niet als bestand. - De bronnen waren al vertrouwd. Het CDN en de API van de leverancier zijn precies de hosts die de Content Security Policy van een winkel zou toestaan. Er verscheen niets nieuws in de script- of connectlijsten. Die hosts toestaan is op zichzelf niet genoeg om een winkel een codestring uit een API te laten uitvoeren: een strikte
script-srczonder'unsafe-inline'of'unsafe-eval'had die geweigerd. Maar winkelthema's en apps leunen sterk op inline scripts, dus weinig winkels kunnen zo'n strikt beleid draaien. - De diefstal gebeurde buiten de site. Het kaartformulier stond op het domein van de aanvaller, dus er verliet geen data de eigen pagina van de winkel. CSP regelt geen top-level navigatie, en de eigen
connect-srcvan de winkel zag het exfiltratieverzoek nooit. - De trigger vereiste een echte klik. Synthetische scanners die pagina's crawlen, of zelfs de winkelwagen laden, klikken niet op Checkout zoals een shopper. Voor hen bleef de lading slapend.
- Het draaide één keer per sessie. Handmatige tests van webwinkels en supportteams kwamen vaak schoon terug, wat meldingen vertraagde en vroege klachten als losse incidenten liet lijken.
- Blokkeerlijsten waren traag. Op 2026-10-10 stond geen van de drie domeinen die Zipp vond op Google Safe Browsing of URLhaus, en zijn adblockers en DNS-filters lieten ze door. Een Reddit-bericht had hetzelfde domein ongeveer 18 dagen eerder al gemeld.
- De checkout van Shopify was in orde. De checkout van Shopify is nooit gecompromitteerd, en dat is precies het punt. De aanval draaide op de winkelpagina's, vóór de betaalpagina, waar de beveiliging van het platform niet reikt.
| Wie kijkt | Wat wordt geladen | Klik op Checkout? | Wat ze zien |
|---|---|---|---|
| Synthetische scanner (periodieke crawl) | Dezelfde scripts van dezelfde hosts | Geen echte klik | Een schone winkel |
| Echte shopper, eerste sessie | Dezelfde scripts van dezelfde hosts | Ja | De nep-checkout |
| Webwinkel die opnieuw test in dezelfde sessie | Dezelfde scripts van dezelfde hosts | Ja | De echte checkout |

De enige betrouwbare plek om deze aanval te zien is waar hij werkelijk draaide: in de browser van een echte shopper, op het moment dat het script de checkoutknop omleidde.
Indicatoren van compromittering
De domeinen zijn onschadelijk gemaakt. Bezoek ze niet.
| Indicator | Type | Context |
|---|---|---|
biliing[.]top | Domein | Nep-checkout op /check-out/, data verstuurd naar /api/submissions |
checkout-confirm[.]top | Domein | In de domeinconfiguratie van de lading |
order-confirm[.]top | Domein | In de domeinconfiguratie van de lading |
account-confirm[.]top | Domein | Gemeld door een ontwikkelaar bij een tweede getroffen winkel |
billing-confirm[.]top | Domein | Gemeld door een ontwikkelaar bij een tweede getroffen winkel |
45.197.2.217 (AS54801) | Hosting | Waar de phishingsite biliing[.]top naar resolvede |
__ctf_shim_handoff_done_v1 | Sleutel in sessieopslag | Markeert dat de shopper al is omgeleid |
__ctf_checkout_txn_v1 | Sleutel in sessieopslag | Gezet samen met de omleiding; doel onbekend |
hijack | Functienaam | Klikhandler die de echte navigatie naar de checkout annuleert |
advanced_users.custom_js | API-veld | Waar de lading zat in het configuratieantwoord van Hulk Product Options |
Vind je een __ctf_-sleutel in de sessieopslag van je winkel, beschouw dat dan als een bevestigde treffer van deze campagne.
Wat webwinkels nu moeten doen
Heb je een Shopify-winkel met apps van derden, ga er dan van uit dat je moet controleren, ook als je nooit iets van HulkApps hebt geïnstalleerd.
- Test de checkout in een nieuwe sessie, meerdere keren. Open een nieuw privévenster, voeg een product toe, klik op de gewone Checkout-knop en let op de adresbalk. Sluit het venster en herhaal. Doe het ook vanuit de winkelwagenlade en op een telefoon. Je checkout moet op je eigen domein of je
myshopify.com-adres blijven. - Zoek de sessiemarkering. Open na een test DevTools, ga naar Application en daarna Session storage, en zoek naar sleutels die beginnen met
__ctf_. - Controleer appinstellingen die code accepteren. Elke app met een veld voor "aangepast JavaScript" of "aangepaste HTML" is een plek waar code zich kan verstoppen. Open ze allemaal en controleer of je alles herkent.
- Inventariseer je app-embeds. Maak in de thema-editor een lijst van alle ingeschakelde app-embeds. Schakel uit en verwijder wat je niet actief gebruikt, en controleer het thema daarna op achtergebleven snippets.
- Vernieuw inloggegevens. Wijzig je Shopify-wachtwoord en je wachtwoord op het dashboard van elke appleverancier, en zet tweestapsverificatie aan waar het wordt aangeboden. Controleer de toegang van medewerkers.
- Vind je het, bewaar dan eerst bewijs. Maak een schermafbeelding van de neppagina met zichtbare URL, sla een HAR-bestand op vanuit het tabblad Network en noteer de tijd. Schakel daarna de app uit, neem schriftelijk contact op met de leverancier, open een zaak bij Shopify Support en licht je betaalprovider in.
- Vraag advies over meldplichten. Kaartgegevens die zijn ingevuld op een neppagina die via je winkel werd bereikt, kunnen verplichtingen scheppen tegenover klanten of kaartmaatschappijen. Overleg met je betaalprovider en juridisch adviseur.
Een waarschuwing van getroffen webwinkels in de Shopify Community-thread: een bevestiging van de leverancier dat de code weg is, was niet altijd genoeg voor Shopify om een winkel weer te laten openen. Leg alles schriftelijk vast.
De PCI DSS 4.0.1-invalshoek
Eisen 6.4.3 en 11.6.1 van PCI DSS 4.0.1 bestaan precies voor dit soort aanvallen. 6.4.3 vraagt webwinkels elk script op betaalpagina's te inventariseren, elk ervan te verantwoorden en te bevestigen dat het geautoriseerd en intact is. 11.6.1 vraagt om een mechanisme dat ongeautoriseerde wijzigingen in die pagina's detecteert zoals de browser van de shopper ze ontvangt. Beide zijn sinds 2025-03-31 verplicht.
Veel Shopify-winkels gaan ervan uit dat deze eisen het probleem van Shopify zijn. Voor de checkout zelf klopt dat grotendeels, zoals we bespraken in maakt Shopify je PCI-compliant?. Maar sinds januari 2025 moeten webwinkels die met SAQ A valideren bevestigen dat hun site niet kwetsbaar is voor scriptaanvallen die hun e-commercesystemen kunnen raken. Een winkelscript dat je checkout ongemerkt vervangt door die van iemand anders is daar precies een voorbeeld van. Vraag je acquirer welke verplichtingen voor jou gelden.
Dit incident laat ook zien waarom een statische scriptinventaris op zichzelf niet genoeg is. De inventaris had hulkcode.js terecht als geautoriseerd vermeld. Wat veranderde was het gedrag: het haalde nieuwe code op, injecteerde die, koppelde een klikhandler en stuurde de shopper naar een domein dat de winkel nooit had gebruikt. Om dat te zien moet je kijken wat scripts werkelijk doen in echte sessies, niet alleen welke bestanden laden.
Hoe cside dit soort aanvallen benadert
Echte sessies, geen synthetische crawls. cside monitort scripts van derden in echte shoppersessies in plaats van te vertrouwen op een periodieke scan. Een lading die alleen bij een echte klik op Checkout actief wordt, één keer per sessie, draait dan nog steeds voor onze ogen.
Gedrag, niet alleen de bron. We volgen wat elk script doet: de code die het injecteert, de listeners die het koppelt, de data die het leest en waar het die naartoe stuurt. Een vertrouwd appscript dat plotseling nieuwe code in de pagina schrijft en shoppers naar een domein stuurt dat je winkel nooit heeft gebruikt, is op zichzelf een signaal, niet iets dat verborgen blijft achter een toegestane hostnaam.
Gestopt in de sessie. Met Script Method haalt cside elk script van derden server-side op om het te hashen, te archiveren en te analyseren, en blokkades worden tijdens runtime in de browser afgedwongen, naast CSP. Een ongeautoriseerd script, of een specifieke functie die het probeert te gebruiken, wordt in de sessie gestopt in plaats van achteraf gemeld.
Geen enkele losse controle had elke variant van deze campagne tegengehouden. Maar de les is bij elke getroffen leverancier dezelfde: als code van derden in de browsers van je klanten draait, heb je zicht nodig in de browsers van je klanten. Het is dezelfde les als die van de supply-chainaanval op Polymarket eerder dit jaar, via een andere leverancier en tegen een ander soort slachtoffer.
Wat we nog niet weten
- Hoe de aanvallers binnenkwamen. HulkApps spreekt van een exploit en Logbase van toegang tot een interne tool. Geen van beide heeft een grondoorzaak gepubliceerd.
- Of de incidenten met elkaar te maken hebben. Gedeelde domeinen en identieke
__ctf_-markeringen wijzen op dezelfde dader, maar geen leverancier en ook Shopify heeft dat niet bevestigd. - Hoeveel winkels en shoppers zijn getroffen. Shopify heeft geen cijfers gepubliceerd.
We werken dit artikel bij zodra leveranciers en Shopify meer publiceren. De eer voor de ontdekking, de reverse engineering en de openbare tijdlijn gaat naar Roman Zipp.
De details hierboven geven openbare berichtgeving en verklaringen van leveranciers weer per 2026-10-16.
Wil je zien wat er werkelijk draait in de browsers van je shoppers? Begin gratis of boek een demo voor een gesprek met ons team.








