A hacker doesn't need your password to hurt your site. Sometimes all they need is a form field that doesn't check what gets typed into it.
That's the idea behind cross-site scripting, or XSS: a small piece of code slipped into your site through a comment box, a contact form, or an outdated plugin, then quietly running in the browser of anyone who loads that page. No obvious defacement. No stolen login screen. Just a script sitting there, waiting.
It's also one of the most common ways WordPress sites get compromised, and one of the least understood outside of a developer's world. Most of what's written about it assumes you can read code. This one doesn't.
Here's what XSS actually is, how it usually gets onto a site like yours, why keeping everything updated isn't the whole answer, and what you can check yourself before you need to call anyone.
What Is XSS, in Plain English
Cross-site scripting, or XSS, is what happens when an attacker gets a small piece of code onto your website, and your visitors' browsers run that code without question.
A browser trusts your website's own content completely, the same way a receptionist waves through anyone already holding an employee badge. It doesn't check who actually wrote each script or where a piece of text originally came from. If your site prints something back to a visitor, whether that's a comment, a search result, or a form response, the browser treats it as yours.
XSS abuses that trust. An attacker sneaks a script into a place your site will display it later, and when someone's browser loads that page, it runs the script the same way it runs code your developer wrote.
One thing worth separating early. XSS is not the same as your site already being hacked. It's the open door, not proof someone has walked through it yet. A vulnerability can sit unused for months before anyone touches it, or it can be exploited the same day it appears.
Why It Matters for a Business Website
Most explanations of XSS stop at "hackers can run scripts." That's true, but it skips the part that actually costs you money.
If Google's Safe Browsing system catches an injected script on your site, it can flag your domain as unsafe before you even notice anything is wrong. Visitors see a red warning screen instead of your homepage. Traffic drops the same day, and getting that warning lifted takes time you don't get back.
XSS is also one of the quieter ways spam gets injected into a site, the same kind of spam that fills your pages with gambling or pharmaceutical links you never wrote. Search engines punish that, and once your rankings drop for it, recovering them is slower than losing them.
If you run a WooCommerce store, the stakes are more direct. A script running on a checkout or account page can read session data while a customer is logged in. That is not an abstract risk. That is a shopping cart your customer trusted you with.
And if you manage sites for clients, this is usually how the conversation starts. A scan flags something, the client forwards you the report, and they want a plain answer, not a CVE number.
How XSS Actually Gets Onto a WordPress Site
XSS doesn't arrive in one shape. It shows up in three different ways, and knowing which one you're dealing with changes how serious it is.
Stored XSS does the most damage over time. The malicious code gets saved somewhere on your site, inside a comment, a product review, a form submission, and it runs again for every visitor who loads that page afterward. One bad comment left unmoderated can quietly run for weeks before anyone notices.
Reflected XSS doesn't get saved anywhere. It rides in on a link. Someone sends a visitor a crafted URL, often through a phishing email or a spam message, and the code only runs for whoever clicks it. Nothing changes on your site itself. The damage happens to that one visitor's browser, not your database.
DOM-based XSS is the rarest of the three on a typical business site. It happens entirely inside the visitor's browser through page-side JavaScript, without your server ever seeing the malicious part of the request. Worth knowing it exists. Not something most site owners need to lose sleep over.
What these three actually do once they're running covers a wide range. On the mild end, a script can deface a page, swapping out text or images so visitors see something you never published. In the middle, it can quietly redirect visitors to another site entirely, the kind of thing you only notice when a customer calls asking why your homepage sent them somewhere strange. On the more serious end, it can hijack an active session, meaning if an administrator is logged in when the script runs, the attacker can act with that administrator's own access. And increasingly, it gets used to inject SEO spam, hidden links and text stuffed into your pages that only search engines see, the kind that quietly wrecks your rankings while your site still looks normal to you. The Japanese keyword hack is one well-documented version of this pattern.
On an ordinary WordPress site, the entry points are rarely exotic. A comment section that doesn't filter submissions. A contact or quote form. A product review field. A search bar that echoes back whatever someone typed into it. An outdated plugin or theme with a known flaw nobody patched. None of these require a sophisticated attacker. Most are found by automated tools scanning thousands of sites at once, not someone targeting you specifically.
↗️
Need Help Cleaning Your Site?
Our security experts remove malware, fix vulnerabilities, and protect your site.
Get Free Security Check
Why "Just Keep Everything Updated" Isn't Enough
Updating everything is the advice you'll read everywhere, and it's not wrong. It's just incomplete.
There's a gap between when a vulnerability becomes public and when you actually apply the fix, and that gap is exactly when attackers move fastest. A known flaw gets published, automated bots start scanning for it within hours, and any site that hasn't updated yet is an open target during that window, sometimes for days.
Some plugins never get fixed at all. A developer abandons a project, the vulnerability stays public, and updating simply isn't an option anymore because there's nothing to update to. This is part of a bigger pattern. Our piece on how trusted plugins get backdoored shows how deep this problem can go.
This is the argument for a second layer, something like a firewall that can block a known attack pattern while you're still in that gap. Not instead of updating. Alongside it. Keeping software current closes the door. It doesn't guard the door while it's still open.
Can You Check This Yourself?
Not every part of this needs a developer, and it helps to know which part you're looking at before you pay someone to look at it.
What a business owner can genuinely check without touching code: an unexpected redirect that sends visitors somewhere else when they land on your site, a pop-up or login form that looks slightly off, an admin user in your WordPress dashboard that nobody on your team remembers creating, a plugin or theme installed that nobody remembers installing, or a security warning showing up in Google Search Console. None of that requires reading a single line of code. It requires looking.
What genuinely needs a developer or a security specialist: confirming whether a specific plugin's code is actually vulnerable, reviewing custom code or a theme built specifically for your site, or cleaning stored XSS out of a database without accidentally deleting real content along with it. Stored XSS in particular is not a find-and-delete job. Get it wrong and you either leave the payload behind or take half your content with it.
If what you're seeing matches the first list, you don't need to self-diagnose further. That's exactly what a security audit is for, and it's a lot cheaper than guessing wrong.
How to Prevent XSS on Your Site
None of this needs a computer science degree. It needs a short list of habits, done consistently instead of once and forgotten.
Update everything, then go further. Keep WordPress core, every plugin, and every theme on their latest version. Then delete anything you've stopped actively using instead of just deactivating it. A deactivated plugin's files often still sit on your server, and an old install nobody remembers is still a door even when nobody is walking through it.
Keep admin accounts few, and lock each one down. Every extra administrator is another password that can leak, another inbox that can get phished. Put two-factor authentication on every admin account without exception. If a password does get stolen, 2FA is usually the difference between a locked door and an open one.
Put a firewall in front of your site. A security plugin with a firewall built in can block a known malicious request before it ever reaches your code. This matters most in the gap between a vulnerability going public and you actually applying the fix, exactly when automated attacks move fastest.
Moderate what visitors can submit. Comment sections, open forms, and review fields are the most common entry point on an ordinary WordPress site. Turning on comment moderation, requiring an account to leave a review, or adding basic spam filtering closes off the easiest path in without inconveniencing a real visitor. Our guide on stopping comment, form, and registration spam covers this in more depth.
Limit what a script can do even if one gets through. A Content Security Policy tells the browser which sources of script are allowed to run at all, so even an injected script pointing at an outside server can get blocked before it executes. It takes some testing to set up without breaking a page builder or analytics tool, usually a developer's job, but it's a real second layer, not just theory.
Watch for warnings instead of waiting to notice something's wrong. A vulnerability scanner or a security plugin's alert system tells you about a risk the moment it's known, not weeks later when a visitor complains. Relying on memory to check for updates is how most of these gaps stay open longer than they should.
What to Do If You Think Your Site Is Already Affected
If you're seeing real warning signs, don't start clicking around trying to fix things one by one. Move in this order.
Back up first, even if you think the backup is infected. A compromised backup still preserves evidence. Deleting the wrong file before you've captured what happened is how people lose the ability to figure out what actually went wrong. Our guide on investigating an attack before you clean it walks through this properly.
Scan files and the database, not just files. A file-only scan misses stored XSS payloads sitting in comments, posts, or plugin settings saved in your database.
Remove any administrator account you don't recognize. Do this before anything else on the list. An unrecognized admin account undoes every other fix you make.
Update or replace the specific vulnerable plugin or theme. Not everything on the site. The one that let this in.
Clear every cache afterward. Page cache, plugin cache, and any CDN cache. A cached copy of the infected page can keep serving the old script long after you've cleaned the source.
This article is about spotting XSS, not walking through a full cleanup. If your site is actively compromised, our hacked WordPress site recovery case study covers the complete process step by step.
The Bottom Line
WordPress gets targeted by XSS so often for the same reason it powers so much of the web: plugins, themes, forms, and comment sections that let anyone build almost anything, which also means dozens of places where user input has to be handled correctly. That flexibility isn't the problem. Leaving it unwatched is. The fix isn't fear. It's knowing which warning signs you can spot yourself, and which parts are worth a developer's five minutes before they become a much longer conversation.