Web Security & OWASP (50 Qs)•Part 2: OWASP Top 10 & Critical Vulnerability Deep-Dives (11 - 25)
Cross-Site Scripting (XSS): Reflected vs. Stored vs. DOM-Based XSS mechanics and cookie exfiltration.
The 3 Flavors of Cross-Site Scripting
XSS occurs when an application includes untrusted user data in a web page without proper validation or escaping, allowing attackers to execute arbitrary JavaScript in the victim's browser session.
sql
+-----------------------+---------------------------------------------------------------+
| XSS Type | Execution Flow & Lifecycle |
+-----------------------+---------------------------------------------------------------+
| 1. Reflected XSS | Malicious script in URL param -> Echoed back in server HTTP |
| (Non-Persistent) | response. Payload executed immediately on victim click. |
+-----------------------+---------------------------------------------------------------+
| 2. Stored XSS | Script saved permanently in DB (comments, forum posts, profile|
| (Persistent) | name) -> Executed on every victim who views the page! |
+-----------------------+---------------------------------------------------------------+
| 3. DOM-Based XSS | Purely client-side. Vulnerable JS reads from sink (location) |
| | and writes unsanitized into DOM (innerHTML, eval). |
+-----------------------+---------------------------------------------------------------+
DOM XSS Sources and Sinks
- Sources (Input):
location.search,location.hash,document.referrer,window.name. - Dangerous Sinks (Execution):
element.innerHTML,document.write(),eval(),setTimeout("code").
Framework Protections (React & Angular)
Modern frontend frameworks encode dynamic variables by default (e.g., React's {userInput} renders as plain text). However, vulnerabilities arise when developers bypass protections:
- React:
dangerouslySetInnerHTML={{ __html: dirtyHtml }} - Angular:
bypassSecurityTrustHtml(dirtyHtml) - Mitigation: Sanitize dynamic HTML using DOMPurify before rendering:
typescript
import DOMPurify from 'dompurify';
const cleanHtml = DOMPurify.sanitize(userContent);
return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />;