Join our Newsletter — 33% off our NHI Course
Home› Guides› Client-Side Security Guide: Magecart and Script Risk
Guide Application Security

Client-Side Security Guide: Magecart and Script Risk

← All guides
By Lalit Choda, NHI Mgmt Group Updated 17 October 2026 17 min read
On this page

Every script on a web page runs with the full authority of the page, so a single altered third-party file can read card numbers, passwords and session tokens as users type them. WAFs, code review and server-side scanning never see that code execute: it runs in the visitor's browser, often from a CDN, vendor or tag manager container nobody in engineering reviewed. This guide covers the browser-side supply chain, web skimming at a defensive level, the PCI DSS v4.0.1 payment page requirements 6.4.3 and 11.6.1, Subresource Integrity, Content Security Policy reporting, DOM-based XSS, Trusted Types and cross-site leaks, where tokens should live in the browser, extension risk and monitoring. It is for application security engineers, front-end leads and whoever answers to a QSA for payment pages.

Key takeaways

  • Inventory what the browser actually loads, not what the repository contains: tag managers and vendor scripts add code at runtime that bypasses your build.
  • PCI DSS 6.4.3 and 11.6.1 are now mandatory for payment pages: every script authorised, integrity-assured and justified, and tamper detection on the headers and scripts the browser receives.
  • Pin and hash what you can, isolate what you cannot. Subresource Integrity works for static, versioned files; dynamic vendor scripts need a cross-origin iframe, a strict CSP or a server-side alternative.
  • Treat DOM sinks as an attack surface. Trusted Types, now Baseline across current browsers, turns string assignments to innerHTML, eval and script src into policy-checked operations.
  • Keep long-lived tokens out of JavaScript reach. One malicious script can read everything in localStorage; HttpOnly cookies or a backend-for-frontend remove that prize.

What runs in your users' browsers

Each source of code in the rendered page has a different owner and changes in a different way.

SourceWho can change itTypical riskPrimary control
First-party bundles (your build)Your developers and your CI/CD pipelineCompromised dependency bundled at build time; poisoned pipelineDependency pinning and review, build provenance, code review
Open source libraries loaded from a public CDNThe package maintainer, the CDN operator, whoever controls the domainUnpinned "latest" URLs pick up a malicious release; domain changes handsExact version pinning, SRI, or self-hosting
Vendor scripts (analytics, chat, payments, fraud, advertising)The vendor, at any time, often without noticeVendor server compromise; scripts that load further scripts (fourth parties)Contract terms, isolation in iframes, CSP, monitoring
Tag manager containersMarketing and analytics users with publish rightsNew tags published outside change control; stolen tag manager accountRestricted publish rights, MFA, approval workflow, monitoring
Browser extensionsThe extension developer, or whoever steals their accountRead and modify pages and cookiesAllowlists for staff; nothing for customers

OWASP's Third Party JavaScript Management Cheat Sheet names the main threat: "The single greatest risk is a compromise of the third party JavaScript server." Vendor code runs with the privileges of the user's session, so OWASP's starting point is the right one: "Audit the scripts actually loaded before claiming that only first-party code executes." Micro frontends from separate teams share one origin, so one team's third-party addition can read every fragment's DOM and storage: inventory each fragment's pipeline. See the Software Supply Chain Security Guide.

Web skimming and Magecart at a defensive level

Magecart is the umbrella name researchers gave to groups that inject payment skimmers into checkout pages. In formjacking or e-skimming, altered JavaScript copies card fields to an attacker-controlled server while the real payment completes normally. Neither shopper nor processor sees anything unusual, and the stolen data never touches the merchant's servers.

  • British Airways (2018): RiskIQ attributed the breach to Magecart. The ICO fined the airline £20 million in October 2020; data for about 429,612 customers and staff was affected, including card numbers and security codes.
  • polyfill.io (2024): after the domain was sold, the script served from cdn.polyfill.io redirected visitors to scam sites, affecting more than 100,000 sites according to BleepingComputer, which reported Sansec's finding that the code "only activates on specific mobile devices at specific hours". Conditional payloads are why one-off manual checks miss injected code.

In ATT&CK terms, skimmers sit at T1059.007 JavaScript (the page cites FIN6 using JavaScript "to steal payment card data from e-commerce sites"), delivered through T1195.002 Compromise Software Supply Chain or T1189 Drive-by Compromise. Skimmer code is usually obfuscated, so compare content and behaviour against an approved baseline rather than rely on signatures.

PCI DSS v4.0.1 requirements 6.4.3 and 11.6.1

Both requirements became mandatory on 31 March 2025 and target the payment page as it is received by the consumer browser, not as it sits on your server.

RequirementWhat the standard saysEvidence an assessor will expect
6.4.3"All payment page scripts that are loaded and executed in the consumer browser must be managed as follows: A method is implemented to confirm that each script is authorized. A method is implemented to assure the integrity of each script. An inventory of all scripts is maintained with written business or technical justification for why each is necessary."Script inventory with owner and justification; an authorisation record (change ticket or approval) per script; the integrity method (SRI hash, CSP hash or nonce, or monitoring that verifies content)
11.6.1"A change- and tamper-detection mechanism is deployed as follows: To alert personnel to unauthorized modification (including indicators of compromise, changes, additions, and deletions) to the security-impacting HTTP headers and the script contents of payment pages as received by the consumer browser." The mechanism must evaluate the received headers and payment page at least weekly, or at a frequency set by a targeted risk analysis under 12.3.1.Tool or process configuration, alert routing to a named team, alert history and how alerts were handled; the targeted risk analysis if the frequency is not weekly
  • Iframes split the responsibility: per PCI SSC guidance, scripts on the parent page are the merchant's and scripts inside the provider's iframe are the provider's. Where scripts create the iframe, 6.4.3 and 11.6.1 apply to them.
  • Full redirects: the requirements do not apply when the shopper is redirected entirely to a compliant provider's page, but the redirecting code is still a target.
  • SAQ A merchants: in January 2025 PCI SSC replaced 6.4.3 and 11.6.1 in SAQ A with an eligibility criterion: the merchant must confirm their site "is not susceptible to attacks from scripts that could affect the merchant's e-commerce system(s)". FAQ 1588 allows techniques such as those in 6.4.3 and 11.6.1, or confirmation from a compliant provider whose instructions are followed. The work is much the same.

Scoping, SAQ types and the rest of the standard are covered in the PCI DSS 4.0 Guide.

Controlling what loads: SRI, CSP and isolation

Subresource Integrity

The integrity attribute takes sha256, sha384 or sha512 hashes; if the delivered file does not match, the browser refuses to load it and returns a network error. It works on <script> and on <link> for stylesheets, preload and modulepreload. Cross-origin files need crossorigin="anonymous" and CORS headers, or the check always fails. Generate hashes in the build (openssl dgst -sha384 -binary file.js | openssl base64 -A). The newer Integrity-Policy header, with a report-only variant, blocks scripts loaded without integrity metadata and reports integrity-violation events.

Content Security Policy with reporting

Host allowlists are weak: MDN cites a case where Google Analytics needed 187 Google domains allowlisted. A strict CSP uses per-response nonces or hashes: script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none', plus tight connect-src and form-action to limit where a skimmer can send data. Deploy first as Content-Security-Policy-Report-Only (not allowed in a meta tag) with Reporting-Endpoints and report-to, keeping the deprecated report-uri alongside. Violation reports double as a real-user tamper signal for 11.6.1. See the Security Headers Guide.

Choosing the control

ControlStopsDoes not stopUse when
SRIAny change to a specific static fileScripts the file loads later; vendors that update in placeVersioned libraries and assets you host or pin
Self-hostingCDN or vendor domain compromise and domain saleA malicious version you copied in; you own updatesLibraries without a vendor service behind them
Strict CSP (nonce or hash)Injected inline and unapproved external scripts; exfiltration to unlisted hosts if connect-src is tightMalicious code inside an approved script; 'strict-dynamic' trusts what approved scripts loadAny page you control end to end
Cross-origin iframe with sandboxVendor code reading the parent DOM, cookies and form fieldsAttacks inside the iframe; weak postMessage handlingPayment fields, chat widgets, advertising
Server-side tagging or collectionThird-party code in the browser at allVendor UI that must render client-sideAnalytics and marketing events on sensitive pages

For iframes, use the sandbox attribute and re-enable only what the frame needs, and on postMessage name the target origin rather than * and match the sender's origin exactly: OWASP calls a substring test such as message.origin.indexOf(".owasp.org")!=-1 "very insecure".

DOM-based XSS, Trusted Types and JavaScript-specific flaws

DOM-based XSS happens when attacker-controlled data reaches a browser API that executes it. MDN groups these injection sinks into HTML sinks (innerHTML, outerHTML, insertAdjacentHTML, document.write(), iframe srcdoc), JavaScript sinks (eval(), the Function() constructor, string arguments to setTimeout()) and script URL sinks (script.src, importScripts(), Worker(), service worker registration).

  • Trusted Types: with require-trusted-types-for 'script' in the CSP, passing a plain string to those sinks throws a TypeError; code must pass a value from a named policy (trustedTypes.createPolicy()) that usually wraps a sanitiser, and the trusted-types directive lists permitted policy names. MDN marks the API Baseline since February 2026. Start in report-only mode and use a default policy only as a transition aid.
  • Prototype pollution: recursive merges of user input "without first sanitizing the keys" let __proto__ keys from a URL fragment or parsed JSON add properties to every object. PortSwigger notes that on the client this "commonly leads to DOM XSS". Block __proto__, constructor and prototype keys in merge utilities and use Object.create(null) or Map for lookups.
  • DOM clobbering: HTML elements with id or name attributes can shadow global variables and document properties that scripts trust. Configure sanitisers to strip those attributes from user content and avoid relying on implicit globals.
  • Cross-site leaks (XS-Leaks): OWASP describes these as "a browser side-channel attack": another site infers facts about a signed-in user from signals such as frame counts, timing or error events. Defences are headers: SameSite cookies, Fetch Metadata checks that reject unexpected Sec-Fetch-Site: cross-site requests to sensitive endpoints, Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Resource-Policy: same-origin and CSP frame-ancestors.

See the Web Application Attacks Guide.

Where identity fits: tokens in the browser

Single-page applications often keep OAuth access and refresh tokens in localStorage, which any script on the origin can read. OWASP is direct: "Do not store session identifiers in local storage as the data is always accessible by JavaScript," and "A single Cross Site Scripting can be used to steal all the data in these objects." A stolen refresh token is a long-lived credential that works from the attacker's machine, which maps to ATT&CK T1528 Steal Application Access Token and T1539 Steal Web Session Cookie.

Storage optionReadable by page scriptsPersistenceAssessment
localStorageYesUntil clearedAvoid for tokens and session identifiers
sessionStorageYesTab or window lifetimeSmaller window, same XSS exposure
In-memory JavaScript variableYes, while the page runsPage lifetimeAcceptable for short-lived access tokens with a protected refresh mechanism
Cookie with HttpOnly, Secure, SameSiteNoSet by serverPreferred for sessions; add CSRF defences
Backend-for-frontend (server holds OAuth tokens, browser holds a session cookie)NoServer-controlledStrongest pattern for high-value applications

Set session cookies with the __Host- prefix, which requires Secure, Path=/ and no Domain attribute, binding it to the exact host. HttpOnly cookies are still sent with fetch() calls, so an injected script can act as the user while the page is open even if it cannot steal the cookie; short token lifetimes and sender-constrained tokens limit the damage. See the Token and Session Security Guide and the OAuth 2.0 and OpenID Connect Guide.

Tag managers and browser extensions

Both change what runs on your pages outside your release process.

Tag managers and consent

A tag manager is a deployment pipeline that bypasses your deployment pipeline. OWASP advises: "Restrict tag-manager publishing access and review changes as application code", and protect the tag manager account with two-factor authentication. Separate editing from publishing, require approval for tags on login or checkout pages, and keep payment pages out of the container where possible. A data layer limits what vendors receive, but OWASP warns "A data layer is not a sandbox".

Tags that fire before consent or collect form contents also create privacy exposure: map each tag to a consent category and test that it stays silent when consent is refused. See the Consent Management Guide: Cookies, CMPs and GPC.

Browser extensions

Extensions with broad host permissions can read and change every page a user visits, outside your CSP. You cannot control customers' extensions, another reason to keep tokens out of script-readable storage. For staff, allowlist extensions through enterprise browser policy (in Chrome, ExtensionInstallBlocklist set to * with ExtensionInstallAllowlist, and ExtensionSettings with runtime_blocked_hosts to keep extensions off payment and admin sites). The Cyberhaven Chrome extension breach shows how OAuth consent phishing against one developer turned a trusted extension into malware in users' browsers (ATT&CK T1176.001 Browser Extensions). See the Enterprise Browser and Browser Security Guide.

Monitoring and detection

Two approaches satisfy 11.6.1; many organisations use both.

AspectSynthetic crawling (agentless)In-page agent (script on the page)
How it worksHeadless browsers load your pages on a schedule and record scripts, network calls and headersA monitoring script runs in real users' browsers and reports scripts and behaviour
CoverageOnly the paths, geographies and devices you simulate; conditional skimmers can hideReal sessions, including device-specific and time-specific payloads
Trade-offNo user impact; detect onlyAdds a script that must itself be inventoried; some can block
Best fitWeekly 11.6.1 evidence, smaller estatesHigh-volume checkout, heavy third-party use

Make crawlers reach the payment step, vary user agents and locations, and diff each run against the approved inventory. Send CSP and Integrity-Policy reports to the SIEM; alert on new script origins, new outbound destinations and security-impacting header changes.

Metrics that show it is working:

  • Percentage of scripts on payment and login pages with owner, justification and authorisation (target 100).
  • Percentage of static third-party scripts protected by SRI or served from your own origin.
  • Time from an unauthorised script or header change to alert triage, against your incident response target.
  • CSP violation reports per week by directive, trending down after rollout, with each new origin investigated.
  • Number of tag manager users with publish rights, and publishes made without approval (target 0 on sensitive pages).
  • Number of application flows that still store tokens in localStorage (target 0).

Implementation plan

  1. Discover: crawl payment, login and account pages with a headless browser, recording every script, origin and header.
  2. Inventory and justify: record each script's owner and justification; remove anything nobody will own. This is your 6.4.3 inventory.
  3. Pin and hash: replace "latest" CDN URLs with exact versions, add SRI to static files, and self-host libraries with no service behind them.
  4. Isolate: move payment fields into the provider's iframe or hosted fields, and move vendor widgets off sensitive pages or into sandboxed iframes.
  5. CSP in report-only: run a strict policy in report-only mode for two to four weeks, fix legitimate violations, then enforce. Rollback is removing the enforcing header while keeping the report-only one.
  6. Trusted Types and tokens: run Trusted Types in report-only, fix sinks, then enforce; move tokens out of localStorage.
  7. Monitor and govern: turn on 11.6.1 change detection, route alerts to a named team with a runbook, and put tag publishing under change control.

A small merchant using a provider's hosted fields can usually meet the requirements with steps 1 to 4 and weekly synthetic monitoring. A large retailer with dozens of vendor scripts should expect step 5 to take several release cycles and consider an in-page agent on checkout.

Framework mapping

Control areaPCI DSS v4.0.1NIST CSF 2.0NIST SP 800-53 Rev. 5CIS Controls v8.1ISO/IEC 27001:2022ATT&CK (v20)
Script inventory and authorisation6.4.3ID.AM-02, GV.SC-07CM-7, SA-9, SR-32.7, 16.4A.5.21, A.8.9T1195.002
Script integrity and DOM XSS6.4.3, 6.2.4PR.PS-01, PR.PS-06SI-7, SI-10, SC-1816.1A.8.26, A.8.28T1059.007
Change and tamper detection11.6.1DE.CM-09SI-4, SI-78.2A.8.16T1189
Token storage and sessionsn/aPR.AA-03SC-23, IA-516.1A.8.5T1528, T1539
Browser extensionsn/aPR.PS-01CM-7, CM-112.5, 9.4A.8.19T1176.001

Common failure patterns

  • Unpinned CDN URLs: loading @latest or a major-version alias means the next published version runs on your page without review. In the Lottie Player npm compromise, versions 2.0.5 to 2.0.7 were reportedly published with a maintainer's stolen token, and sites loading the unpinned library from a CDN showed visitors a wallet-draining prompt.
  • Forgotten script domains: a tag pointing at a sold or lapsed domain runs whatever the new owner serves, as with polyfill.io.
  • Inventory from the repository, not the browser: tag manager and vendor-loaded scripts are missing, so the 6.4.3 inventory is wrong on day one.
  • Monitoring that only checks the home page: skimmers target the checkout step, and conditional payloads fire only for some devices and times.
  • CSP left in report-only forever, or enforced with 'unsafe-inline' and wildcard hosts: evidence of a control without the protection.
  • Refresh tokens in localStorage: one injected script becomes persistent account access that survives closing the browser.

Practitioner checklist

  • Crawl payment and login pages and build a script inventory with owner, justification and authorisation for each entry.
  • Pin every third-party library to an exact version (never @latest) and add SRI with crossorigin="anonymous" to static files.
  • Put payment fields in the provider's iframe or hosted fields, and keep vendor widgets off payment pages.
  • Deploy a strict nonce- or hash-based CSP with tight connect-src and form-action, report-only first.
  • Enable Trusted Types in report-only mode, fix sinks, then enforce require-trusted-types-for 'script'.
  • Move session and refresh tokens out of localStorage into __Host- HttpOnly, Secure, SameSite cookies or a backend-for-frontend.
  • Restrict tag manager publish rights, require MFA and approval, and map every tag to a consent category.
  • Run 11.6.1 change and tamper detection at least weekly, or as set by a targeted risk analysis, with alerts routed to a named team.

Standards and references

Related NHI Mgmt Group resources: PCI DSS 4.0 Guide · Token and Session Security Guide · Enterprise Browser and Browser Security Guide · Consent Management Guide: Cookies, CMPs and GPC · Security Headers Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 17 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org