The Fake Stripe Card Form Skimming Online Shops

The Fake Stripe Card Form Skimming Online Shops

We’ve been tracking a Magecart skimming kit that steals card details by replacing a shop’s payment option with a fake form styled to look like Stripe’s.

Pick a payment option at checkout and, on an infected shop, the box under it is quietly replaced with a new payment form styled to look like a Stripe payment form. Type your card in, click 'Place Order', and the details go to the attacker. The fake form then disappears, the real payment option reappears, and the customer might wonder why they were asked for payment details twice.

As of today this kit is already live on dozens of shops across WooCommerce, PrestaShop and Magento, served from 55 attacker hosts that we've detected so far.

What the shopper sees

This is a real checkout, captured over the weekend on a live shop, and we've got dozens of screenshots like this.

Every form is a copy of Stripe's Card Element, with the same placeholder text ("1234 1234 1234 1234", "MM / YY", "CVC"), the same CVC icon, and Stripe's own card-brand images loaded straight from js.stripe.com. The kit copies the design presumably because it's the card form that shoppers will recognise and trust the most. We captured the same thing on shops in Cyprus (JCC gateway), Bangladesh (SSLCommerz), India (Razorpay and PhonePe), Vietnam, Pakistan, Romania (NETOPIA), Lithuania, Spain, Thailand and France.

How it got onto the shops

On every WordPress shop we checked, it sits in the page <head> wrapped in <!-- Google Tag Manager --> … <!-- End Google Tag Manager --> comments, starts with a genuine-looking GTM bootstrap line and a made-up container ID (GTM-3BC4300, GTM-7F1F9A9, GTM-E9EB98A…), and then carries on into the real payload: base64 strings holding a contract address, the per-shop script path, a list of public Sepolia RPC relays, and a link to ethers.js on a public CDN. On PrestaShop and Magento shops the same loader, or a plain <script src> for the skimmer, appears among the theme's own module scripts.

The snippet may have been added through one of three routes:

  1. An admin account. Weak, reused or phished WordPress credentials, with no second factor. Once in, the snippet is pasted into the theme's "header scripts" setting or a header-and-footer snippet plugin, where it looks like any other tag.
  2. A plugin or module with a hole. Several of the shops run current core versions, so this isn't a WordPress or PrestaShop core bug. Abandoned or unpatched plugins and modules that let an attacker write options or files are the usual route onto an otherwise patched site.
  3. Stolen hosting or FTP credentials. Infostealer malware on the owner's or developer's machine hands over the control-panel login, and the loader is written straight into header.php or a module template.

The victim shops run different themes, page builders and plugins, and we found no single component common to all of them that could be the culprit. That points away from one plugin zero-day and towards stolen access, one shop at a time.

How it works

The process starts with a compromise of the shop that allows the initial JavaScript injection. From there:

  1. A loader on the shop page finds the skimmer host. The shop's page doesn't contain the attacker's hostname. It contains a small loader that asks an Ethereum Sepolia smart contract, through public JSON-RPC relays (0xrpc.io, 1rpc.io, ethereum-sepolia-rpc.publicnode.com), where the next stage lives. Change the contract, and every infected shop moves to a new host without the attacker touching any of them again.
  2. Each shop gets its own script. The skimmer is served from a path named after the shop: https://<host>/<n>/<shop>/<random>.js. The filenames are picked to look like build output: runtime.module.js, vendor.validator.min.js, analytics_z54sl.js, metrics.js.
  3. A per-shop config decides what to replace. The script carries a config block that names the checkout URL keyword, the payment option to attack (input[name="payment_method"][value="payfast"]:checked), the element to replace (.payment_box.payment_method_payfast) and the button that fires the theft (#place_order). On PrestaShop and Magento shops the selectors are copied from the live DOM. It looks like someone built each one by hand.
  4. On Place order, the data is exfiltrated. Card number, expiry, CVC, plus the billing name, address, email and phone from the checkout form, are POSTed to a PHP endpoint on the same host (/<n>/<shop>/data-handler.php, lib-service.php, nav-engine.php, cdn-bridge-src.php), or over a WebSocket to lightstars.top or pixeldoomi.top. The config also has options for an image-pixel beacon and a relay through another PHP host if the first route is blocked.
  5. Then it cleans up. The click on Place order is deliberately not blocked ("Sending data without blocking action", in the kit's own debug strings), so the real checkout proceeds as normal. A hundred milliseconds later the data is sent, the fake form is hidden, the shop's real payment box has its display: none removed, every observer and listener the kit installed is torn down, and an already_checked flag is set in the browser so the same shopper never sees the form again. There's an optional reload-after-send and a redirect URL for configs that need them. For gateways that open a popup, the kit does block the click, takes the data, then fires the gateway's original action itself.

What to do

This is exactly the kind of threat that Report URI was built to deal with. Our JavaScript Integrity Monitoring solution was built to deal with malicious JavaScript on your site, and we have specific protections for Magecart attacks like this.

If you want to see what JavaScript your checkout is really loading, a 30-day trial of Report URI has data flowing within a few minutes and no credit card required.
Get Started Now →

Indicators of Compromise

amberkernel.com        ashenravenfort.top     backgroundshadows.top  bleakhaven.com
bloodboundcitadel.top  bloodthornkeep.top     brightstars.top        cedarfable.com
cedarmotive.com        cedarribbon.com        darkflamewatch.top     emberwarden.com
frontsky.top           frozenwildheart.top    ghostharvest.com       hiddenmorrow.com
ironwolfcrest.top      ivoryfable.com         marblehabit.com        meriksstanet.top
mildrocket.com         mistwalkerforge.top    morrowtheory.com       mossparlor.com
mosstransit.com        mournguardian.com      paleanchor.com         pixelkanion.top
pixelmonsterlittle.top pixelslayermon.top     shadowmatrixpls.top    shadowrunevail.top
shadowshadows.top      silvermorrow.com       stylebaliamston.com    stylebenjamin.com
stylecladis.com        styledontcryyy.com     styleilios.top         stylekanions.com
stylenemesiis.com      styleokis.top          styleolivvs.top        styleouserpan.com
stylerightnoww.com     styleucandoit.com      styleuseless.com       styleussles.com
voidravenbastion.com   voidravencitadel.com   wildreceipt.com        willowtransit.com

Exfiltration endpoints.

https://<kit host>/<n>/<shop>/{data-handler,lib-service,nav-engine,cdn-bridge-src,site-build,site-validate,base-handler-dx,api-check,cache-resolve-wp}.php
https://styleoust.top/
https://merikssmurfik.top/api/accept-metrics
wss://lightstars.top/custom-ws
wss://pixeldoomi.top/custom-ws

Path shapes (for hunting in your own CSP reports or proxy logs):

/<digit>[A-Z0-9]*/<shop-name>/<name>.js      e.g. /3/<shop>/storage_7wq0a.js, /3N2/<shop>/analytics_z54sl.js
/<shop-name>/metrics.js                      e.g. /<shop>/metrics.js

Loader behaviour (a strong signal on a checkout page): JSON-RPC eth_call POSTs to 0xrpc.io/sep, 1rpc.io/sepolia or ethereum-sepolia-rpc.publicnode.com from a shop that has no reason to talk to a blockchain.

Read more