# Fake Payment Fields: Skimmers That Replace a Hosted Element

Attacks that remove a hosted payment element and render a convincing copy in its place, so card details are typed into attacker-controlled markup on a page that still looks entirely correct.

Provenance: Corroborated by external research.
Published: 2026-08-24. Updated: 2026-08-24.

An embedded payment element is supposed to make skimming impossible. The card fields sit in an
iframe served by the payment provider, your page can't read them, and a skimmer running on your page
has nothing to steal.

That only holds while the real element is the one on the page. An attacker who can run script in the
parent document can remove it and draw their own markup in the same spot. The layout survives, the
styling matches, and the customer types their card into the attacker's fields.

## How the injection arrives authorised

In the campaign we track here, the injection arrived through an abused Google Tag Manager container
and swapped the Stripe Payment Element for a lookalike.

How it got there matters more than the swap itself. A tag manager exists to inject arbitrary script
into your pages on demand, and any policy that allows one has already agreed to that. An attacker
with access to the container isn't getting round a control, they're using one. The script comes from
a host you trust, at a point where you expect script to load, and the only thing wrong with it is
what it does.

## Why inventory beats a source check

Asking whether a script came from an approved source doesn't help here, because it did. The question
that tells the injected tag apart from the real ones is whether anybody signed off on *this script*
running on *this page*, and can say why it needs to be there.

That's what PCI DSS 6.4.3 asks, and it asks it per script on the payment page rather than per source
host. A tag manager sails through a source check and fails an inventory check the moment it starts
serving something nobody approved.

## What the iframe boundary guarantees

It's worth being precise about what a hosted payment element actually guarantees, because this
attack lives in the gap.

The guarantee is real, and it's narrow: script in your page can't read across the origin boundary
into the provider's iframe. Card details typed into the real element genuinely are out of reach of
anything running on your page.

What it doesn't do is guarantee the element is still there. Your page owns the layout, so script in
your page can remove the iframe, hide it, shrink it to nothing, or draw its own fields next to it.
None of that needs to read across the boundary, so the isolation doesn't stop any of it.

Your customer can't tell. A real hosted field and a good copy look identical, and the padlock, the
domain and the certificate are all still correct, because they're yours and the site really is
yours. Every check a customer has been taught to make still passes while their details go somewhere
else.

## The tag manager problem

Most of the discussion about tag managers stops at "a third party can change your pages". The
bigger problem is that the change turns up already authorised.

A CSP that allows a tag manager allows arbitrary script from it, because that's the whole point of a
tag manager. Narrow that allowance and you break the thing. So source-based control, which works
well against an unfamiliar host, has nothing to offer here: the injection comes from a host you
trust on purpose, at a point where script is meant to load, down a channel built to deliver exactly
this.

That doesn't make tag managers unusable on a payment page, but it changes what the control has to
be. Either the payment page runs no tag manager at all, which is the cleanest answer if you can
afford it, or you inventory the tags it does run one by one and check against that inventory, so an
extra one shows up even though its source was allowed.

## What to look for

The copy still has to send the data somewhere, so the destination turns up as a connection you never
allowed. That's the half that's hard to hide. The fields can be copied convincingly, but the data
still has to leave, and you can see it leaving.

Pair it with a script inventory of the payment page. A swapped element means a script running there
that is not on your authorised list, and the two signals together identify both halves of the
attack — what was added, and where it sent the data.

If your payment page uses a hosted element, it's worth building one specific check: confirm the
provider's frame is actually there, and the size you expect, once the page has loaded. A missing or
collapsed element on a page that should have one isn't a rendering quirk to look at next week.

## Indicators

- *.fontuse.com
- *.sallexyhub.com

## Questions

### Is a hosted payment element enough to stop skimming?

Not on its own. A hosted element keeps card details out of your DOM only while it's the element actually on the page. An attacker who can run script there can remove it and draw a copy in its place, and your customer won't see any difference.

### How does a tag manager become the delivery route?

A tag manager is allowed to inject arbitrary script by design. An attacker who gets into the container inherits that permission, and the injection arrives from a host your policy already trusts, so nothing looks out of place.

### What does PCI DSS 4.0 require here?

6.4.3 asks you to inventory and authorise every script on a payment page and say why each one needs to be there. 11.6.1 asks you to detect unauthorised changes to that page. A swapped payment element is exactly the kind of change 11.6.1 is about.

### How would I detect the swap?

The copy has to send the details somewhere, so that host shows up as a connection you never allowed. A script inventory catches the other half, by showing you a script on the payment page that nobody approved.
