Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject client-side scripts into web pages viewed by other users. This can lead to session hijacking, credential theft, and other security issues.
Reflected XSS occurs when a malicious script is reflected off the web server, such as in an error message, search result, or any other response that includes some or all of the input sent to the server as part of the request.
<script>alert('XSS')</script>
<img src="x" onerror="alert('XSS')">
<svg onload="alert('XSS')">
<body onload="alert('XSS')">
<div onmouseover="alert('XSS')">"Hover over me"<divx>
Stored XSS occurs when a malicious script is injected directly into a vulnerable web application. The malicious script is stored permanently on the target servers and is executed when other users access the compromised page.
<script>alert('Stored XSS')</script>
<img src="x" onerror="alert(document.cookie)">
<a href="javascript:alert('XSS')">Click me</a>
DOM-based XSS occurs when a client-side script writes user-controllable data to the document object model (DOM) in an unsafe way. The vulnerability is in the client-side code rather than the server-side code.
Your account was created on: March 15, 2025
Membership level: Silver
<script>alert('DOM XSS')</script>
<img src="x" onerror="alert(document.domain)">
<iframe src="javascript:alert('XSS')"></iframe>
Always encode user-generated content when outputting to HTML, URLs, JavaScript, CSS, or any other context:
// In PHP: echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8'); // In JavaScript: const textNode = document.createTextNode(userInput); element.appendChild(textNode); // Or in React (automatic encoding): return <div>{userInput}</div>
Implement a Content Security Policy to restrict what scripts can run on your page:
// Add this HTTP header Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;
Validate user input against a whitelist of allowed values:
// In PHP: function isValidUsername($username) { return preg_match('/^[a-zA-Z0-9_]{3,16}$/', $username); } // In JavaScript: function isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }
Modern frameworks like React, Angular, and Vue automatically escape values by default.
Enable the browser's built-in XSS filter:
// Add this HTTP header X-XSS-Protection: 1; mode=block
Protect cookies from being accessed by client-side scripts:
// In PHP: setcookie('session_id', $sessionId, [ 'expires' => time() + 3600, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]);
If you need to allow some HTML, use a library like DOMPurify:
// In JavaScript: const clean = DOMPurify.sanitize(userProvidedHtml); element.innerHTML = clean;
Comments: