XSS Attacks Explained: How to Protect Your Web Applications
Cross-Site Scripting (XSS) is one of the most common web vulnerabilities. Understanding how XSS works and how to prevent it is essential for every web developer.
What is XSS?
XSS occurs when an attacker injects malicious JavaScript code into a web application, which then executes in other users' browsers. This allows attackers to:
- Steal session cookies and tokens
- Capture keystrokes and form data
- Redirect users to malicious sites
- Deface websites
- Spread malware
- Perform actions on behalf of the victim
Types of XSS Attacks
1. Stored XSS (Persistent)
The malicious script is permanently stored on the server (database, file system, etc.) and served to users when they view the affected page.
Example scenario:
Attacker posts a comment with malicious script. When other users view the comment, the script executes and their cookies are stolen.
2. Reflected XSS (Non-Persistent)
The malicious script is reflected off a web server, typically in search results or error messages.
Example scenario:
Vulnerable search page reflects the search term without sanitization, allowing script execution.
3. DOM-based XSS
The vulnerability exists in client-side JavaScript code that improperly handles user input.
Real-World Example: Cookie Theft
Here's how an attacker might steal session cookies using XSS:
The attacker injects a script that steals the user's session cookie and sends it to their server, allowing them to hijack the user's session.
Prevention Method 1: Output Encoding
Always encode user input before displaying it in HTML. Use textContent instead of innerHTML when possible.
Prevention Method 2: Content Security Policy (CSP)
CSP is a powerful defense-in-depth mechanism against XSS. It controls which resources can be loaded and prevents inline scripts from executing.
Prevention Method 3: Sanitization Libraries
Use trusted libraries like DOMPurify to sanitize HTML when you need to display rich content. These libraries remove dangerous elements and attributes while preserving safe HTML.
Prevention Method 4: HTTPOnly Cookies
Set the HTTPOnly flag on session cookies to prevent JavaScript from accessing them. This way, even if XSS occurs, attackers cannot steal session tokens.
Framework-Specific Protection
React: React automatically escapes content by default. Only use dangerouslySetInnerHTML when absolutely necessary, and always sanitize first with DOMPurify.
Vue: Vue escapes by default with double curly braces. Avoid v-html unless you sanitize the content first.
Angular: Angular sanitizes content automatically. Use DomSanitizer for trusted HTML when needed.
Common Mistakes
1. Client-side validation only: Client-side checks can be bypassed. Always validate and sanitize on the server too.
2. Incomplete sanitization: Simple string replacement is not enough. Use proper sanitization libraries.
3. Trusting user input in URLs: Validate URL schemes to prevent javascript: protocol attacks.
Testing for XSS
Test your application with common XSS payloads to ensure proper protection. Look for places where user input is displayed without encoding.
Defense-in-Depth Strategy
Use multiple layers of protection:
- Input Validation: Validate on both client and server
- Output Encoding: Encode all user input before display
- CSP Headers: Implement strict Content Security Policy
- HTTPOnly Cookies: Protect session cookies
- Sanitization: Use DOMPurify for rich content
- Regular Scanning: Automated security testing
XSS Security Checklist
- ✅ Never use innerHTML with user input
- ✅ Use textContent or framework escaping
- ✅ Implement CSP headers
- ✅ Set HTTPOnly on session cookies
- ✅ Sanitize rich content with DOMPurify
- ✅ Validate URLs before href assignment
- ✅ Don't use eval() or similar functions
- ✅ Encode user input in different contexts
- ✅ Regular security audits and testing
Conclusion
XSS is preventable with proper input handling and output encoding. By following these best practices and using modern frameworks correctly, you can eliminate XSS vulnerabilities from your applications.
Remember: Never trust user input, always encode output, and use defense-in-depth strategies.
Detect XSS Vulnerabilities Automatically
ProbCheck scans your code for XSS vulnerabilities and provides detailed fix recommendations. Find and fix XSS before attackers exploit it.
Start Free Scan →