High risk Website · Cross-site scripting
Cross-site scripting (XSS) found: what it means and how to fix it
Short answer: your website puts something a visitor typed, or something from a link, into a page without making it safe. An attacker can use that to run their own JavaScript in your visitors' browsers, on your domain, with your site's trust.
The fix: escape untrusted data wherever it's shown (most templates do this if you let them), stop inserting raw user HTML, update the plugin or theme that causes it, and add a Content-Security-Policy as a safety net.
The three kinds of XSS
- Reflected. The page repeats back part of the request, like a search term in "No results for …". The attacker sends someone a crafted link; clicking it runs the script.
- Stored (persistent). The script is saved, for example in a comment, a review or a contact form shown in an admin panel, and runs for everyone who views it. Usually the most serious.
- DOM-based. The page's own JavaScript takes something from the address bar or elsewhere and writes it into the page, for example with
innerHTML, without escaping it.
Why it matters
- Account takeover. A script can act as the logged-in visitor, or steal session cookies that aren't marked HttpOnly. If an administrator triggers it, the attacker can get admin access.
- Phishing from your address. A fake login form shown on your real domain is far more convincing than one on a lookalike site.
- Defacement and malware. Changing prices, inserting spam links, or sending visitors to malicious downloads.
- 443 Cross Site Scripting (Reflected) Found by the Deep Scan's OWASP ZAP test High
How it was found, and how to confirm it
In a Deep Scan, OWASP ZAP sends harmless test strings into your forms and links and checks whether they come back in a way a browser would run. Its findings name the page and the parameter, for example ?q= on /search. The free Basic Scan's Nmap scripts also look for some XSS patterns, but those are hints that need checking.
- Open the page and parameter from the report on your own site.
- Enter harmless test text such as
"><b>xss-test</b>into that field or link. - If xss-test appears in bold, the page is inserting your input as HTML and is vulnerable. If you see the literal characters
<b>, it's escaping correctly and the finding may be a false positive.
Only test sites you own or have written permission to test.
How to fix it
WordPress and other CMS sites
- Update everything: WordPress core, plugins and themes. Most WordPress XSS comes from a plugin or theme with a published fix. If the affected page belongs to a plugin nobody maintains anymore, replace it.
- In your own theme code, output data with
esc_html(),esc_attr()andesc_url()rather than echoing it directly.
Custom code
- Escape on output, for the right context. Let your template engine do it: React, Vue, Angular, Django, Rails, Laravel Blade and Twig all escape by default. Don't switch it off with
dangerouslySetInnerHTML,v-html,|safe,{!! !!}orrawfor anything a user can influence. - Plain PHP:
echo htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); - JavaScript in the browser: use
textContentinstead ofinnerHTML, and never pass untrusted text toeval()ordocument.write(). - If users must submit HTML (a rich-text editor), clean it with a maintained sanitizer such as DOMPurify before saving or showing it.
Safety nets
- Content-Security-Policy: a strict policy stops injected scripts from running even if a flaw slips through. See the CSP guide.
- HttpOnly cookies: scripts can't read session cookies marked HttpOnly. See the cookie flags guide.
Then re-scan
Run another Deep Scan to confirm the finding is gone. If it was stored XSS, also remove the saved malicious content (the comment, review or form entry) from your database.
Common questions
Isn't input validation enough?
It helps, but escaping at output is what actually prevents XSS. Data can reach a page by routes your validation never saw.
The finding is on a search page that doesn't store anything.
Reflected XSS on a search page still matters: a crafted link to it can run a script for whoever clicks, including logged-in staff.
Do I need the Deep Scan to find XSS?
For a real test, yes. The free Basic Scan checks the server; the Deep Scan's ZAP test crawls your pages and forms. You can compare both on the website scanner page.
Sources: OWASP: Cross Site Scripting · OWASP XSS Prevention Cheat Sheet · ZAP alert: Cross Site Scripting (Reflected) · WordPress: escaping data