XSS injects malicious script into a trusted website so the attacker’s code executes in another user’s browser, often to steal data or hijack sessions. Formjacking targets payment or login forms by intercepting the values users type and sending them to an attacker. Both abuse client-side trust, but XSS focuses on script execution while formjacking focuses on data capture.
How XSS and formjacking differ at the attack surface
XSS is an execution problem. The attacker gets script to run in the browser in the context of a trusted site, so the malicious code can read page content, manipulate the DOM, or act as the user inside that session. Formjacking is a capture problem. The attacker wants the values typed into a specific form, especially payment or login fields, and exfiltrates them before normal submission.
That difference matters because the defender is not protecting the same control point. XSS is usually about breaking the trust boundary between untrusted input and executable script. Formjacking is usually about protecting data in transit inside the page lifecycle, including third-party scripts, injected snippets, and unexpected form listeners.
Modern JavaScript-heavy sites blur the line because both attacks can be delivered through client-side code paths. A malicious script can be used to steal form data, but that does not make every XSS event formjacking. The practical distinction is the attacker’s primary objective: code execution versus data interception. For broader context on malicious JavaScript supply-chain abuse and exposed secrets, see Shai Hulud npm malware campaign.
Why the distinction changes detection and control design
XSS defenses focus on preventing executable content from reaching the browser and reducing what that script can do if it lands. That means encoding, sanitisation, strict content handling, and browser-side policy enforcement matter because the core risk is script execution and session abuse. Formjacking defenses focus more on integrity of form handling, script provenance, and monitoring for changes to fields, listeners, and checkout or authentication flows.
Practically, XSS often produces visible behavioural changes such as unexpected DOM writes, script execution, or account actions taken in the victim’s session. Formjacking may be quieter, because the page can appear normal while keystrokes or field values are siphoned off in the background. That makes integrity monitoring and third-party script control especially important in payment and login flows.
If you are mapping either pattern to wider web security controls, the main difference is whether you need to stop unsafe execution or stop unsafe collection. For baseline control coverage, NIST Cybersecurity Framework 2.0 helps structure protect, detect, respond, and recover activity around the browser-facing application surface, while the OWASP API Security Top 10 is a useful companion when the same front end feeds backend transaction paths.
Practitioner guidance for JavaScript teams
What to prioritise: Treat XSS as a code execution threat and formjacking as a data interception threat. That means your first question is different: “Can attacker script run here?” for XSS, and “Can attacker code observe or alter form values here?” for formjacking.
What to verify: In a checkout or login page, confirm which scripts are allowed to run, which fields can be read, and whether any third-party JavaScript has unnecessary access to sensitive inputs. If you cannot explain why a script needs access to payment or credential fields, it is already too powerful.
Common mistake: Teams often deploy generic input validation and assume they have addressed both threats. Validation helps, but it does not stop a malicious script already executing in the browser, and it does not stop a compromised dependency from reading form values before submission.
Practitioner takeaway: Use the attack objective to drive the control strategy: block script execution paths for XSS, and tightly constrain script provenance and form-field access for formjacking.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Agentic AI Top 10 address the attack and risk surface, while CIS Controls v8 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| CIS Controls v8 | CIS 16 — Application Software Security | XSS and formjacking are application-layer JavaScript threats. |
| CIS 3 — Data Protection | Formjacking targets sensitive form data before it is transmitted. | |
| CIS 8 — Audit Log Management | Client-side abuse often requires detection through logging and telemetry. | |
| Recommendation — Harden web application code to prevent unsafe client-side execution and data exposure. Protect sensitive form inputs and limit where they can be processed or exposed. Collect and review web and application telemetry for abnormal script or form behavior. | ||
| OWASP Agentic AI Top 10 | A1 — Prompt Injection and Input Manipulation | Client-side injection logic parallels the input manipulation pattern behind XSS. |
| A6 — Tool Misuse and Unauthorized Action | Malicious browser script can misuse page capabilities and user context. | |
| Recommendation — Validate and constrain untrusted input before it can influence executable behavior. Constrain what active code can do in the browser session and with user-authorised actions. | ||
| NIST CSF 2.0 | PR.DS — Data Security | Formjacking is fundamentally about preventing sensitive data exposure. |
| Recommendation — Protect sensitive browser-entered data from capture, leakage, and unauthorized disclosure. | ||
Related resources from NHI Mgmt Group
- What is the difference between Content Security Policy and Subresource Integrity in JavaScript security?
- What is the difference between CSRF and XSS in web security?
- What is the difference between frontend and backend JavaScript security scanning?
- What is the difference between dynamic scanning and CodeQL based analysis for modern JavaScript security testing?