Formjacking is malicious JavaScript injected into a website's forms that steals what users type (card numbers, credentials, personal data) before the form is even submitted. It executes in the visitor's browser after the page is served, so WAFs and server logs never see the theft happen.
TL;DR: what is formjacking
- What formjacking is: JavaScript injected onto a form to steal what users type before submit. Card fields, credentials, or PII.
- Invisible to your WAF: It runs in the browser after the page is served. Your WAF and origin logs see nothing. The compromised script sits inside a trusted allowlisted domain.
- How to address it: Compliance path: 6.4.3 script inventory and 11.6.1 tamper detection. Technical path: in-session monitoring.
Short on time? See cside's in-browser Magecart and skimmer blocking. It covers everything below in one deployment.
How formjacking works
A formjacking attack runs in four steps.

The diagram traces one checkout (shop.example[.]com/checkout) across five stages, and shows why a network-layer view stays blind while a browser-layer view catches it:
| Stage | What happens in the browser | What the server / CSP sees |
|---|---|---|
| 1. Checkout page | Shopper types card number + CVV into the real form | Normal page load |
| 2. Tampered vendor script | widget.js (modified) loads like any other third-party tag | An allowed, already-trusted script URL |
| 3. Form skimmer | Injected listener hooks every input field and reads keystrokes in real time | Nothing, no server request |
| 4. Exfil endpoint | Encoded copy sent to cdn-metrics[.]example via POST /collect?d=eyJjYyI6…, disguised as an analytics beacon | Looks like ordinary analytics traffic |
| 5. Attacker | Stolen cards resold or used for carding fraud; the real payment still completes | No anomaly, transaction succeeds |
The network layer is blind because the exfil request leaves the browser straight to the attacker domain. cside watches the browser layer, so the injected listener and the outbound beacon are caught where they actually run.
1. Get code onto the page. The attacker plants JavaScript on the target page, almost always without the site owner's knowledge. The most common route is compromising a third-party script, an analytics tag, a chat widget, an A/B testing tool, or a payment library, so the skimmer arrives packaged inside code the site already trusts and loads on every checkout.
2. Hook the form fields. Once the script loads, it attaches event listeners to the payment or login form. A listener on the input event fires on every keystroke; one on the submit event fires when the user clicks pay. The script can also read values directly from the DOM after fields are populated.
3. Copy the data. The listener captures field values, card number, expiry, CVV, billing address, exactly as the user entered them. The form itself is not touched. The user's transaction still goes through the real payment processor.
4. Exfiltrate. The stolen data is encoded and sent to an attacker-controlled domain, often disguised as an analytics ping or an image request so it blends into the page's normal outbound traffic. Most Content Security Policy headers do not block this because the attacker either uses a domain the policy already permits or exploits an existing gap.
How attackers get formjacking code onto your site
Formjacking does not require a direct breach of your servers. The three most common delivery routes:
Third-party script compromise. Most payment and e-commerce pages load 20-60 third-party scripts, analytics platforms, chat tools, tag managers, payment libraries, widgets from marketing vendors. Any one of those vendors is an attack surface. If the attacker compromises the vendor's CDN or infrastructure, every site that loads that script receives the skimmer. The 2018 British Airways breach put the personal data of 429,612 customers at risk after attackers modified JavaScript in the airline's payment flow. Researchers linked the attack to Magecart threat actors using a compromised third-party supplier script, not a direct breach of British Airways' own servers. (Wikipedia: British Airways data breach)
Expired or hijacked domains. Sites sometimes load scripts from third-party domains that have since expired or changed ownership. An attacker who registers that domain can then serve any JavaScript they want to every site still loading the old script tag. Because the URL has not changed and the domain previously served legitimate code, no automated check immediately flags it.
Direct code injection. If the attacker exploits a vulnerability in the site's CMS, admin panel, or a plugin, they can inject the formjacking script directly into the site's own files. This route requires greater access but leaves no external dependency to track.
What formjacking targets
Attackers prioritize pages that collect high-value data with minimal friction:
| Page type | Data typically captured |
|---|---|
| E-commerce checkout | Card number, expiry, CVV, billing address |
| Account registration | Email, password, name, postal address |
| Login pages | Username and password |
| Healthcare intake forms | Insurance ID, date of birth, health information |
| Financial account applications | SSN, income, bank account details |
Checkout pages are the primary target because card data has an immediate resale market. Login credentials are the second priority because they enable account takeover on platforms with stored payment methods.
What is PII harvesting?
PII harvesting is the systematic collection of personally identifiable information (names, emails, credentials) by scripts reading form fields in the browser; the full definition and techniques are covered in what is PII harvesting. Formjacking is PII harvesting applied to payment forms: the same field-hooking mechanism, aimed at card data on checkout pages, credentials on registration forms, or insurance identifiers on intake forms. Server-side controls cannot stop either, because the theft happens in the browser before the data is encrypted or submitted.
Why traditional security tools miss formjacking
Web application firewalls protect traffic reaching your server. Formjacking data leaves the browser directly to an attacker domain, the WAF never sees it.
Server-side scanners inspect code at rest on your origin. A compromised third-party script loads from a vendor's CDN at runtime, so it is never on your server to scan.
Periodic manual reviews check the scripts listed in your tag manager or code repository. A skimmer injected into a third-party script between review cycles is invisible until someone runs the next audit, often weeks later.
Subresource Integrity (SRI) protects scripts you hash at deploy time. It cannot protect scripts loaded from vendor-controlled CDNs where the attacker has write access, or scripts dynamically loaded at runtime.
PCI DSS 4.0.1 requirements 6.4.3 and 11.6.1 exist because the industry recognized this gap. Script inventory and continuous tamper monitoring on payment pages became mandatory on 1 April 2025, not optional best practice. (PCI Security Standards Council)
Skimmers also actively evade scanners. Most check navigator.webdriver, which returns true in headless automated browsers, and serve clean code to security tools while running the full skimmer for real users. A scanner that crawls the page from outside may find nothing while the attack is live.
How to detect formjacking
Detecting formjacking requires visibility into what JavaScript does at runtime in real visitors' browsers. The specific signals to monitor:
- New or modified scripts on sensitive pages. A script that was not present the day before, or whose content changed outside a scheduled deployment, is the first indicator.
- Unexpected event listeners on form fields. Legitimate code attaches
submitlisteners to process forms. A listener oninput,keydown, orkeyupevents on payment or credential fields, added by a third-party script, is a formjacking signature. - Outbound data to unlisted domains. Any network request from a payment page to a domain not on your approved allowlist warrants immediate investigation.
- Encoded payloads in outbound requests. Formjackers encode stolen data, often in base64, before sending it. A beacon containing an unusually long encoded parameter that does not correspond to any known analytics event is a red flag.
The key constraint is that only monitoring inside the browser can see these signals for real. Scanners operating from the outside miss formjacking that gates itself to real users.
How to prevent formjacking
No single control eliminates every formjacking route. Layering several controls significantly narrows the attack surface:
-
Inventory every script on sensitive pages. Know every first- and third-party script loading on checkout and login pages, who authorized it, and why it is there. Unrecognized scripts should not load.
-
Monitor for changes continuously. A script that changes between audit cycles is an undetected breach. Continuous tamper monitoring, mandatory under PCI DSS 4.0.1 req. 11.6.1, catches changes within minutes rather than weeks.
-
Apply SRI where practical. For scripts you fully control and version yourself, SRI hashes verify the script has not changed since deployment. SRI breaks for frequently-updated third-party scripts and for scripts dynamically generated per request.
-
Scope your Content Security Policy tightly. A strict CSP limits which domains scripts can send data to, reducing where a skimmer can exfiltrate. In practice, payment pages often need to permit many domains for legitimate analytics and payment functionality, making a complete block difficult without custom implementation effort.
-
Deploy real-visitor client-side monitoring. The most direct defense is monitoring that watches what every script does in real browsers, not a scanner running synthetic requests from outside. This is the approach cside takes.
How cside detects formjacking in real browsers
cside deploys as a single first-party JavaScript snippet that monitors script behavior in real visitors' browsers, not a crawler or scanner operating from outside.
For formjacking, cside detects:
- Event listeners attached to form fields by third-party scripts, with particular attention to listeners that fire on keystrokes rather than form submit
- Outbound data requests to domains not on the site's approved allowlist
- New scripts appearing on payment or login pages outside a deployment window
- Changes to existing scripts, including runtime modifications to a loaded vendor tag
Because cside operates at the browser layer alongside the attack, it catches the skimmer as it fires rather than after data has already been exfiltrated. For organizations subject to PCI DSS 4.0.1, PCI Shield maps this monitoring to requirements 6.4.3 (script inventory and authorization) and 11.6.1 (tamper detection), generating QSA-ready reports continuously.
For context on how formjacking relates to the broader digital-skimming ecosystem and Magecart threat groups, see the companion guide: Formjacking vs Magecart vs Digital Skimming. For a complete breakdown of how these injection attacks work in practice, the Magecart attack guide covers entry points, detection gaps, and prevention layers in depth. The underlying discipline for addressing both is client-side security, which extends beyond formjacking to cover every script running in visitor browsers.
Book a demo to see what cside finds running on your payment pages, or read more about e-skimming prevention.








