ProbCheck LogoProbCheck
Back to Blog
Security

XSS Attacks Explained: How to Protect Your Web Applications

March 15, 2025
11 min read

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:

  1. Input Validation: Validate on both client and server
  2. Output Encoding: Encode all user input before display
  3. CSP Headers: Implement strict Content Security Policy
  4. HTTPOnly Cookies: Protect session cookies
  5. Sanitization: Use DOMPurify for rich content
  6. 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 →