Security
What is an XSS attack, and how do you prevent it?
Cross-site scripting lets an attacker run their script in your visitors' browsers. The three types, how frameworks protect you, and where XSS still gets in.
Cross-site scripting, XSS, happens when a site includes untrusted input in a page in a way that lets it run as JavaScript. The attacker's script then runs as your site in visitors' browsers and can steal data or act as the user. Prevent it by escaping output, avoiding raw HTML insertion, and adding a Content Security Policy.
Published · Last updated
How it works
Browsers trust every script on your page equally. If a user's input, such as a comment, a name or a URL parameter, is placed into the page as HTML, a value containing a script tag or an event handler becomes code. That code can read what the page shows, send requests as the logged-in user, and read tokens stored in localStorage.
The three types
- Stored: the malicious input is saved, for example in a comment, and served to every visitor who views it.
- Reflected: the input comes from the URL or a form and is echoed back in the response, so a crafted link attacks whoever clicks it.
- DOM-based: the page's own JavaScript takes input from the URL or storage and writes it into the page unsafely.
How frameworks protect you, and where they do not
React, Vue, Svelte and Angular escape values inserted into templates by default. That removes most XSS. It still gets in through:
- dangerouslySetInnerHTML in React, v-html in Vue, and innerHTML in plain JavaScript.
- Rendering user-written Markdown or rich text without sanitising the resulting HTML.
- Links built from user input, where a javascript: URL runs code on click.
- Third-party scripts and widgets that you do not control.
// unsafe el.innerHTML = comment; // safe el.textContent = comment;
How to prevent it
- Let the framework escape output, and treat every raw HTML insertion as a security review.
- Sanitise HTML you must render, with a maintained library such as DOMPurify.
- Allow only http and https in user-supplied links.
- Add a Content Security Policy that blocks inline scripts without a nonce. It turns many XSS bugs into blocked console messages.
- Keep session cookies HttpOnly, so injected script cannot read them.
Input validation alone does not stop XSS. What matters is how data is output, in which context: HTML, attribute, URL or script.
What a scan can and cannot tell you
WebAuditOS checks for an enforced Content Security Policy and warns when it allows unsafe inline script without a nonce or hash, and fails when the effective checked script policy allows unsafe-eval. It checks nosniff and HttpOnly on session-like cookies. These limit what an XSS bug can do.
It does not inject payloads or test forms, so it cannot find XSS vulnerabilities themselves. That takes code review and authorized testing.
A strong CSP does not mean there is no XSS. It means an XSS bug does less damage.
Short answers
Does React prevent XSS? It escapes by default. dangerouslySetInnerHTML and unsafe links bypass that.
Is XSS still common? Yes. It remains one of the most frequently reported web vulnerabilities.
Does HTTPS prevent XSS? No. HTTPS protects the connection, not the page content.
What is the best defence? Correct output escaping, plus a Content Security Policy as a second layer.
In the product
The checks this maps to
Every check named here runs on every scan, on every plan - what a plan changes is how many pages are crawled, how long the history is kept and what you can do with the result. These are the ids the findings carry, so you can match a line in a report to the explanation above.
- sec.headers.csp - Content-Security-Policy header
- sec.csp.unsafe-eval - CSP does not allow 'unsafe-eval'
- sec.headers.nosniff - X-Content-Type-Options: nosniff
- sec.cookies.httponly - Session cookies HttpOnly
Read next
Security
What is a Content Security Policy, and how do you add one?
A Content Security Policy tells the browser which scripts and resources may run on your page. How to roll one out safely, and which directives matter.
Security
What is CSRF, and do you still need a CSRF token?
Cross-site request forgery tricks a logged-in browser into sending a request it did not intend. How SameSite changed it, and when tokens are still needed.
Security
What is SQL injection, and how do you prevent it?
SQL injection lets an attacker run their own database queries through your app. How it works, the fix that prevents it, and where it still appears today.