Skip to content
Sovereign SecureSovereign Secure

Glossary

Cross-Site Scripting (XSS): How It Works and How to Prevent It

Updated

What cross-site scripting is, the three main types, why it matters on payment pages under PCI DSS v4.0.1, and how developers and testers deal with it.

Prefer to talk? Call +44 161 523 5276

  • A worked XSS example, unencoded and encoded
  • Stored, reflected and DOM-based XSS compared
  • Why XSS matters for PCI DSS 6.4.3 and 11.6.1
  • Prevention that works in modern frameworks

The short answer

Cross-site scripting (XSS) is a web application vulnerability that lets an attacker run their own JavaScript in another user's browser, because the site places untrusted input in a page without encoding it. The script runs with the site's trust, so it can hijack sessions, change what users see or capture card details typed into a checkout.

On this page
  1. What is an example of cross-site scripting?
  2. What are the types of XSS?
  3. What can an attacker do with an XSS attack?
  4. Why does XSS matter on payment pages?
  5. How do you prevent cross-site scripting?
  6. How do penetration testers find XSS?
  7. Why Sovereign Secure?

Cross-site scripting (XSS) happens when a web application takes data an attacker controls and puts it into a page without making it safe, so the browser runs it as code. The target is your users, not your server: the script runs on your domain, in their session, with their permissions. Since 2021 the OWASP Top 10 has grouped XSS under Injection, as the current 2025 list still does. For related terms, see the cyber security glossary.

What is an example of cross-site scripting?

Take an online shop whose search page repeats the search term back to the user. A normal search requests /search?q=shoes and the page includes <p>Results for shoes</p> in its HTML.

An attacker sends a customer a link with a script in place of the search term, such as /search?q=<script>alert(document.domain)</script>, URL-encoded so it survives in a link. What happens next depends on whether the page encodes its output:

  • Unencoded (vulnerable): the server returns <p>Results for <script>alert(document.domain)</script></p>, and the browser runs the script on the shop’s domain, inside the customer’s session.
  • Encoded (safe): the server returns <p>Results for &lt;script&gt;alert(document.domain)&lt;/script&gt;</p>, and the browser simply shows the text as part of the search term.

The alert is a harmless proof that testers use. A real attacker would swap it for a script that sends keystrokes or session data to their own server, or rewrites the checkout form. This is reflected XSS. If the shop also saved search terms and showed them to other visitors, for example in a “popular searches” box, the same flaw would become stored XSS.

What are the types of XSS?

The three main types differ in where the payload lives.

Type Where the payload lives How a victim is hit Typical example
Stored (persistent) Saved by the application, usually in its database Anyone who views the affected page A review, support ticket or profile name that renders script for every viewer
Reflected (non-persistent) In the request, usually a URL parameter The victim opens a crafted link A search page that echoes the search term back without encoding
DOM-based Handled only by client-side JavaScript The page’s own script writes attacker data into the page Code that reads location.hash and writes it with innerHTML

Blind XSS is a stored variant that fires where the attacker cannot see it, such as an internal admin console, so the victim is usually a privileged member of staff.

What can an attacker do with an XSS attack?

Whatever the user could do on that page:

  • Act as the user, or steal session tokens that scripts can read
  • Change the account email or password to take the account over
  • Show a fake login prompt on your genuine domain
  • Read personal data or admin records displayed on the page

Why does XSS matter on payment pages?

XSS is one route for a card-skimming script to reach an e-commerce checkout. Injected JavaScript can capture card numbers as they are typed, or swap an embedded payment form for a fake one. The card data is stolen even though your servers never store it, and is then used for card-not-present fraud elsewhere.

PCI DSS v4.0.1 tackles this from several directions:

Requirement What it expects
6.2.4 Bespoke and custom software is engineered to prevent common attacks, with cross-site scripting named in the requirement
6.4.2 Public-facing web applications are protected by an automated solution that detects and prevents web-based attacks (mandatory from 31 March 2025)
6.4.3 Every script loaded on a payment page is authorised, has its integrity assured and is inventoried with a business or technical justification (mandatory from 31 March 2025)
11.4.1 Penetration testing includes application-layer testing for, at a minimum, the vulnerabilities listed in 6.2.4
11.6.1 A change and tamper detection mechanism alerts on unauthorised changes to the security-impacting HTTP headers and scripts of payment pages as the browser receives them (mandatory from 31 March 2025)

Which apply depends on how you take payments. Since January 2025, SAQ A omits 6.4.3 and 11.6.1 but requires merchants to confirm their site is not susceptible to attacks from scripts that could affect their e-commerce systems, which an XSS flaw on the page hosting the payment form would undermine. Our guides to SAQ A vs SAQ A-EP eligibility and PCI DSS 6.4.3 and 11.6.1 for e-commerce go further.

How do you prevent cross-site scripting?

Encode output for the context it lands in, and avoid code paths that bypass that encoding. Input validation helps but is not enough, because data that is safe in one context can be dangerous in another.

  1. Use your framework’s auto-escaping and review every escape hatch, such as dangerouslySetInnerHTML in React, v-html in Vue or the bypassSecurityTrust functions in Angular.
  2. Encode for the context. HTML body, HTML attributes, JavaScript, CSS and URLs each need different encoding.
  3. Prefer safe DOM APIs such as textContent over innerHTML, and never pass untrusted data to eval() or similar functions.
  4. Sanitise rich text with a maintained library such as DOMPurify where users must be allowed to write HTML.
  5. Add defence in depth: a strict Content Security Policy and HttpOnly session cookies limit the damage if a flaw slips through.

The OWASP Cross Site Scripting Prevention Cheat Sheet sets out the encoding rules for each context.

How do penetration testers find XSS?

Testers map every input, from URL parameters and form fields to headers, file names and API fields, trace where each comes back out and send payloads built for that context. Stored inputs are followed to every screen that displays them, including back-office tools, and blind payloads call back to the tester if they fire somewhere unseen. DOM-based XSS is found by reading the client-side JavaScript for dangerous sources and sinks.

Automated dynamic application security testing (DAST) finds many reflected cases quickly. Manual web application penetration testing and source code review catch the stored and DOM-based issues that scanners tend to miss.

Why Sovereign Secure?

Our web application and API tests look for XSS by hand as well as with tools, and each finding is confirmed, rated and given a specific fix. As a PCI SSC Qualified Security Assessor company that is also ISO 27001 certified, we show how payment page findings relate to PCI DSS.

Next step: request a penetration testing quote for your website, checkout or API.

Your next step

Last reviewed October 2026 by the Sovereign Secure assessment team.

Trusted by banks, payment providers and global brands

  • Accor
  • Fiserv
  • JCPenney
  • Ticketmaster
  • Nitecrest
  • Cashplus
  • Ahli United Bank
  • Kuwait Finance House
  • AYA Bank
  • Bank of Palestine
  • Liquid Pay
  • DataFlow Group
  • Wilmington
  • The Growth Company
  • Wahyukart

FAQ

Frequently asked questions

Can't find your answer? Call us on +44 161 523 5276 or send us a message.

What is an XSS attack in simple terms?

An attacker gets a website to send their script to your browser as if it were part of the site. Your browser trusts the site, so it runs the script with your session, letting the attacker act as you or read what you see on the page.

Is XSS still common?

Yes. Cross-site scripting (CWE-79) ranked first in MITRE's 2024 CWE Top 25 Most Dangerous Software Weaknesses, and the OWASP Top 10:2025 still covers it under A05 Injection. Modern frameworks have removed many simple cases, but it still turns up in web application tests, most often in rich-text features, older code and single-page app code that writes to the page.

What is the difference between XSS and SQL injection?

Both are injection flaws, but they hit different targets. SQL injection gets the server's database to run attacker input as a query, exposing or changing stored data; XSS gets the victim's browser to run attacker input as script, acting inside that user's session.

Do modern frameworks such as React and Angular prevent XSS?

They escape output by default, which removes most simple cases. XSS still appears where developers use escape hatches that insert raw HTML, build URLs from user input or pass data to functions such as eval.

Does a Content Security Policy stop XSS?

A strict Content Security Policy makes XSS much harder to exploit, but it is a second layer. OWASP treats it as defence in depth rather than the primary fix, so correct output encoding in the code comes first.

What is the difference between XSS and CSRF?

XSS runs the attacker's script inside your site, so it can read pages and act as the user. Cross-site request forgery tricks the browser into sending a request from another site without seeing the response. A working XSS usually defeats CSRF protections too.

Can a vulnerability scanner find XSS?

Scanners find many reflected XSS issues, but they are weaker at stored XSS behind multi-step workflows and DOM-based XSS in single-page apps. Manual web application testing covers those gaps.

Free consultation

Talk to an assessor

We aim to reply within one working day, and send a fixed quote once your scope is confirmed.

  • PCI SSC-approved QSA, QPA, CPSA, P2PE and 3DS assessors
  • IASME-licensed Cyber Essentials certification body
  • Clients across the UK, US, Europe, Middle East and Asia since 2012

“The Cyber Security Services were delivered on time and price was competitive.”

Beverley McGowan, Director, Specialists Hub. Read the full testimonial

By sending this form you agree to us contacting you about your enquiry. See our privacy policy.

We aim to reply within one working day. The first consultation is free.