Skip to main content
Blog
Attacks Blog

De HulkApps-checkoutkaping: hoe vertrouwde Shopify-apps een phishingtrechter werden

De configuratie-API van een Shopify-app leverde een script dat de echte checkout verving door een nep-checkout op biliing[.]top. Wat er gebeurde.

Oct 17, 2026 • 14 min read
De HulkApps-checkoutkaping: hoe vertrouwde Shopify-apps een phishingtrechter werden
Inhoudsopgave

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.

  1. Een vertrouwd bestand laadt. Hulk Product Options levert een thema-extensie die hulkcode.js op winkelpagina's laadt. Het bestand komt van cdn.shopify.com als onderdeel van het extensiepakket. Het was niet aangepast.
  2. Het bestand vraagt zijn configuratie op. Bij het laden van de pagina stuurt hulkcode.js één POST-verzoek naar productoption.hulkapps.com/api/v2/store/get_all_relationships met de winkel-ID en het bekeken product.
  3. 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.
  4. 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.
  5. De klik op Checkout wordt gekaapt. Het script registreert een klik-listener. Als de shopper op Checkout klikt, annuleert een functie die letterlijk hijack heet de echte navigatie en leidt om naar een nagemaakte checkout op een domein van de aanvaller.
  6. De nep-checkout verzamelt de kaart. De nagemaakte pagina imiteert een Shopify-checkout en vraagt om betaal- en persoonsgegevens.
  7. De gegevens vertrekken. Het formulier stuurt alles naar /api/submissions op het domein van de aanvaller, dat antwoordt met een record-ID.
  8. 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_v1 in de sessieopslag zodat het nooit twee keer in dezelfde sessie actief wordt.

Stroomdiagram van de HulkApps-checkoutkaping in acht stappen: de pagina laadt hulkcode.js van het CDN van Shopify, vraagt zijn configuratie op, ontvangt aanvalscode in het veld custom_js, injecteert die tijdens runtime, kaapt de klik op Checkout, toont een nep-checkout, stuurt de kaartgegevens naar de aanvaller en stuurt de shopper terug naar de echte checkout

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.

AppLeverancierWanneerWat er is gezegd
SelleasyLogbase2026-10-13Logbase 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 PlusSwymGemeld op 2026-10-15Een 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 OptionsHulkApps2026-10-10HulkApps 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-appsHextomAugustus 2026Door Zipp genoemd als eerder, opgelost incident. Geen openbare melding van de leverancier gevonden.
Sticky Add to Cart, Mega MenuQikify2026-07-22Qikify 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.js kwam van cdn.shopify.com met 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-src zonder '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-src van 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 kijktWat wordt geladenKlik op Checkout?Wat ze zien
Synthetische scanner (periodieke crawl)Dezelfde scripts van dezelfde hostsGeen echte klikEen schone winkel
Echte shopper, eerste sessieDezelfde scripts van dezelfde hostsJaDe nep-checkout
Webwinkel die opnieuw test in dezelfde sessieDezelfde scripts van dezelfde hostsJaDe echte checkout

Vergelijking van drie bezoekers van dezelfde winkel: een synthetische scanner ziet een schone winkel, een echte shopper wordt bij de eerste klik op Checkout naar de nep-checkout gestuurd, en een webwinkel die in dezelfde sessie opnieuw test ziet 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.

IndicatorTypeContext
biliing[.]topDomeinNep-checkout op /check-out/, data verstuurd naar /api/submissions
checkout-confirm[.]topDomeinIn de domeinconfiguratie van de lading
order-confirm[.]topDomeinIn de domeinconfiguratie van de lading
account-confirm[.]topDomeinGemeld door een ontwikkelaar bij een tweede getroffen winkel
billing-confirm[.]topDomeinGemeld door een ontwikkelaar bij een tweede getroffen winkel
45.197.2.217 (AS54801)HostingWaar de phishingsite biliing[.]top naar resolvede
__ctf_shim_handoff_done_v1Sleutel in sessieopslagMarkeert dat de shopper al is omgeleid
__ctf_checkout_txn_v1Sleutel in sessieopslagGezet samen met de omleiding; doel onbekend
hijackFunctienaamKlikhandler die de echte navigatie naar de checkout annuleert
advanced_users.custom_jsAPI-veldWaar 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.

  1. 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.
  2. Zoek de sessiemarkering. Open na een test DevTools, ga naar Application en daarna Session storage, en zoek naar sleutels die beginnen met __ctf_.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.

Simon Wijckmans
Founder & CEO

Founder and CEO of cside. Previously a product manager on Cloudflare Page Shield (now Cloudflare Client-Side Security). Co-chair of the W3C Anti-Fraud Community Group and a Forbes 30 Under 30 honoree. Building accessible security against client-side attacks, web security is not an enterprise-only problem.

FAQ

Frequently Asked Questions

Geen enkele openbare bron zegt dat de systemen of de checkout van Shopify zijn gecompromitteerd. De kwaadaardige code kwam binnen via configuratiegegevens die apps van derden op de winkelpagina's laadden, en de nep-checkoutpagina's draaiden op domeinen van de aanvaller. Op 2026-10-16 vonden we geen openbare verklaring van Shopify over het incident.

Hulk Product Options van HulkApps was de eerste geïdentificeerde app, op 2026-10-10. Swym Wishlist Plus (Swym) en Selleasy (Logbase) werden in latere meldingen genoemd, en Selleasy bevestigde op 2026-10-13 een incident. Qikify en Hextom hadden vergelijkbare, inmiddels opgeloste incidenten in juli en augustus 2026. Het zijn verschillende leveranciers; HulkApps zegt dat zijn onderzoek geen andere Hulk-app vond die omleidingen uitvoerde.

Het script zette na de eerste omleiding een markering in de sessieopslag, __ctf_shim_handoff_done_v1, en werd in die sessie niet opnieuw actief. HulkApps meldt ook dat sommige browsers de omleiding blokkeerden. Test elke keer in een nieuw privévenster en op meer dan één apparaat.

Het JavaScript-bestand van de app was ongewijzigd en werd geleverd vanaf cdn.shopify.com, dus integriteitscontroles slaagden. De kwaadaardige lading kwam als data van de eigen API van de leverancier, een host die de winkel al toestond. Die hosts toestaan is op zichzelf niet genoeg om geïnjecteerde code uit te voeren, en een strikte script-src zonder 'unsafe-inline' of 'unsafe-eval' had het kunnen blokkeren, maar winkelthema's en apps leunen sterk op inline scripts, dus weinig winkels draaien zo'n strikt beleid. Het kaartformulier stond na een top-level navigatie op het domein van de aanvaller, en die valt buiten CSP.

Contact opnemen met hun kaartuitgever en vragen de kaart te blokkeren, ook als hun echte bestelling normaal is doorgegaan. Webwinkels die de omleiding in hun winkel vinden, moeten hun betaalprovider inlichten en advies vragen over hun meldplichten.

Door te kijken wat scripts werkelijk doen in echte shoppersessies, in plaats van welke bestanden worden geladen. Een vertrouwd appscript dat plotseling nieuwe code injecteert, een handler aan de checkoutknop koppelt en de shopper naar een domein stuurt dat de winkel nooit heeft gebruikt, is een gedragsverandering. Die is zichtbaar in de sessie, ook als elke bron-URL op de toegestane lijst staat.

Monitor en beveilig je third-party scripts

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Start gratis, of probeer Business met een proefperiode van 14 dagen.

cside-dashboardinterface met scriptmonitoring en beveiligingsanalyses
Related Articles
Boek een demo

Wil je dit doornemen met een engineer?

Dertig minuten, op je eigen site. Geen slides.

Boek een persoonlijke demo om te zien:

Hoe je in 1 dag voldoet aan PCI DSS-vereisten 6.4.3 en 11.6.1
Waarom scripts van derden een beveiligingsrisico zijn voor jou en je bezoekers
Hoe je privacy- en toestemmingslekken (AVG, CCPA) bij elke derde partij monitort
Hoe je misbruik van aanmeldingen, account sharing en chargeback-fraude stopt met device intelligence
Hoe je AI-agents en bots die je site bereiken in realtime detecteert en beheerst

Liever gewoon een vraag stellen?

Gebruik ditzelfde e-mailadres wanneer je bij Google boekt. Google kan je vragen het nogmaals in te vullen.

We gebruiken je e-mailadres om je boeking aan je bezoek te koppelen en te meten hoe mensen ons vinden. Dit is geen nieuwsbriefinschrijving.

Lukt het boeken niet? Agenda in een nieuw tabblad openen

Wat wil je oplossen?

Vertel het ons in één zin, dan komen we terug met iets bruikbaars in plaats van een standaardverhaal.

Waar we meestal mee helpen:

Zien welke scripts van derden op je site draaien
Bewijs voor PCI DSS 6.4.3 en 11.6.1
Bots, AI-agents en accountovername

Liever meteen een moment inplannen? Kies een tijdstip