💡

    Running Code Locally

    While this online editor runs real JavaScript, some security examples require a browser environment. Download Node.js to run JavaScript on your computer, use your browser's Developer Console (Press F12) to test code snippets, or create a .html file with <script> tags and open it in your browser.

    Client-Side Security Essentials

    Master XSS prevention, CSRF protection, input sanitization, secure token handling, and defense-in-depth architecture.

    What You'll Learn

    • XSS prevention techniques
    • CSRF token protection
    • Input sanitization
    • Secure token handling
    • Content Security Policy
    • Defense-in-depth architecture

    Why Client-Side Security Matters

    The browser is exposed territory. Anyone can inject HTML, override JavaScript, modify requests, steal tokens, and manipulate the DOM. The only safe approach is to treat all user-controlled input as hostile.

    What Attackers Can Do

    • Steal session tokens and cookies
    • Hijack user accounts
    • Inject fake login forms
    • Execute actions as the user
    • Redirect to malicious sites
    • Install keyloggers

    Your Defense Goals

    • Prevent script injection (XSS)
    • Block forged requests (CSRF)
    • Sanitize all user input
    • Secure token storage
    • Implement CSP headers
    • Build defense-in-depth

    Cross-Site Scripting (XSS) — The #1 Frontend Threat

    XSS occurs when malicious script executes inside your page. Even one tiny mistake can compromise your entire application.

    Three Types of XSS

    • Stored XSS: Malicious script saved in database, shown to all users (comments, profiles)
    • Reflected XSS: Script injected via URL parameters, executed immediately
    • DOM XSS: JavaScript directly puts user input into DOM without server involvement

    XSS Attack Basics

    Understanding and preventing cross-site scripting attacks

    Try it Yourself »
    JavaScript
    // ❌ DANGEROUS - XSS vulnerabilities
    const userInput = '<img src=x onerror="alert(document.cookie)">';
    
    // This allows script execution!
    document.getElementById("output").innerHTML = userInput;
    
    // ✅ SAFE - Use textContent instead
    document.getElementById("output").textContent = userInput;
    // Renders as plain text, not HTML
    
    // ❌ DANGEROUS - Setting href from user input
    const link = document.createElement("a");
    link.href = "javascript:alert('XSS')"; // Executes JS!
    
    // ✅ SAFE - Validate URLs firs
    ...

    HTML Escaping — Your First Line of Defense

    Escaping converts dangerous characters into safe HTML entities. This is essential when you must display user content.

    HTML Escaping

    Escape dangerous characters to prevent XSS

    Try it Yourself »
    JavaScript
    // HTML escape function - prevents XSS
    function escapeHTML(str) {
      const escapeMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;',
        '/': '&#x2F;',
        '`': '&#x60;',
        '=': '&#x3D;'
      };
      
      return String(str).replace(/[&<>"'`=\/]/g, char => escapeMap[char]);
    }
    
    // Test with malicious input
    const maliciousInput = '<script>alert("XSS")</script>';
    const safeOutput = escapeHTML(maliciousInput);
    
    console.log("Original:", maliciousInput);
    console.l
    ...

    DOM-Based XSS — Common in SPAs

    DOM XSS happens when JavaScript reads user input (from URLs, forms, storage) and inserts it into the page without sanitization. This is extremely common in React, Vue, and Angular apps.

    DOM-Based XSS

    Prevent DOM XSS in single-page applications

    Try it Yourself »
    JavaScript
    // DOM-based XSS - when URL params go directly to DOM
    
    // ❌ DANGEROUS - Reading URL and inserting into DOM
    const urlParams = new URLSearchParams("?name=<img src=x onerror=alert(1)>");
    const name = urlParams.get("name");
    
    // This would execute the XSS payload:
    // document.body.innerHTML = "Hello, " + name;
    
    // ✅ SAFE - Always sanitize URL parameters
    function sanitizeParam(param) {
      if (!param) return "";
      
      // Use textContent approach
      const div = document.createElement("div");
      div.textCont
    ...

    Cross-Site Request Forgery (CSRF)

    CSRF forces a victim's browser to make authenticated requests without their knowledge. If your app uses cookies for authentication, you're vulnerable.

    CSRF Defense Layers

    • SameSite cookies: SameSite=Strict or Lax
    • CSRF tokens: Random value verified on each request
    • Origin validation: Check Origin/Referer headers
    • Authorization headers: Use Bearer tokens instead of cookies

    CSRF Protection

    Implement CSRF token protection

    Try it Yourself »
    JavaScript
    // CSRF Attack Example and Defense
    
    // ❌ How CSRF works:
    // 1. User logs into bank.com (session cookie stored)
    // 2. User visits evil.com
    // 3. Evil.com has hidden form:
    /*
    <form action="https://bank.com/transfer" method="POST">
      <input type="hidden" name="amount" value="10000">
      <input type="hidden" name="to" value="attacker">
    </form>
    <script>document.forms[0].submit()</script>
    */
    // 4. Browser sends cookies automatically
    // 5. Bank thinks it's legitimate request
    
    // ✅ CSRF Token Protection
    c
    ...

    Input Sanitization — Clean Everything

    Any time user input appears in HTML, URLs, DOM, or attributes — it must be sanitized.

    Input Sanitization

    Comprehensive sanitization for text, HTML, and URLs

    Try it Yourself »
    JavaScript
    // Comprehensive Input Sanitization
    
    // Basic sanitizer for plain text
    function sanitizeText(input) {
      if (typeof input !== 'string') return '';
      
      return input
        // Remove null bytes
        .replace(/\0/g, '')
        // Normalize unicode
        .normalize('NFC')
        // Trim whitespace
        .trim()
        // Limit length
        .slice(0, 1000);
    }
    
    // HTML sanitizer (basic - use DOMPurify in production)
    function sanitizeHTML(html) {
      // Create temporary element
      const temp = document.createElement('div');
    ...

    💡 Production Tip

    Use DOMPurify for production HTML sanitization. It handles SVG attacks, mutation XSS, and edge cases that simple regex cannot.

    Advanced XSS Vectors

    Even when developers escape <script> tags, attackers exploit less obvious injection points.

    Advanced XSS Vectors

    Watch for event handlers, templates, SVG, and encoding attacks

    Try it Yourself »
    JavaScript
    // Advanced XSS Vectors to Watch For
    
    // 1. Event Handler Injection
    const userAvatar = 'x" onerror="stealCookies()';
    // ❌ DANGEROUS:
    // `<img src="${userAvatar}">`
    // Results in: <img src="x" onerror="stealCookies()">
    
    // ✅ SAFE: Escape attribute values
    function escapeAttr(str) {
      return String(str)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
    }
    
    console.log("Safe attribute:", escapeAttr(userAvatar));
    ...

    Secure Token Handling

    Token theft is the ultimate goal of most XSS attacks. Never store sensitive tokens in localStorage — XSS can steal them.

    ❌ Dangerous Token Storage

    • localStorage (XSS can read it)
    • sessionStorage (XSS can read it)
    • URL parameters (visible in logs)
    • Non-HttpOnly cookies (JS can access)

    Secure Token Handling

    Store and handle tokens securely in memory

    Try it Yourself »
    JavaScript
    // Secure Token Handling
    
    // ❌ DANGEROUS - Token in localStorage (XSS can steal it)
    // localStorage.setItem('token', 'secret-jwt-token');
    
    // ❌ DANGEROUS - Token in URL
    // window.location = '/dashboard?token=secret';
    
    // ✅ BETTER - Token in memory (cleared on page refresh)
    class SecureTokenStore {
      #accessToken = null;
      #tokenExpiry = null;
      
      setToken(token, expiresIn = 3600) {
        this.#accessToken = token;
        this.#tokenExpiry = Date.now() + (expiresIn * 1000);
      }
      
      getToken() {
        
    ...

    Content Security Policy (CSP)

    CSP is a browser-level defense that restricts what scripts can run. Even if an attacker injects a script, CSP can block it from executing.

    Content Security Policy

    Implement CSP headers to block script execution

    Try it Yourself »
    JavaScript
    // Content Security Policy (CSP) - Browser-Level XSS Protection
    
    // CSP is set via HTTP header by the server:
    // Content-Security-Policy: default-src 'self'; script-src 'self'
    
    // Example CSP configurations:
    
    const cspExamples = {
      // Strict - Only same-origin resources
      strict: {
        "default-src": "'self'",
        "script-src": "'self'",
        "style-src": "'self'",
        "img-src": "'self' data:",
        "connect-src": "'self'",
        "frame-ancestors": "'none'",
        "object-src": "'none'"
      },
      
      //
    ...

    Defense-in-Depth Architecture

    No single mechanism protects a modern app. You need layered security — if one layer fails, others prevent disaster.

    Defense-in-Depth Architecture

    Build layered security with multiple protection mechanisms

    Try it Yourself »
    JavaScript
    // Defense-in-Depth Security Architecture
    
    class SecureApp {
      constructor() {
        this.csrfToken = this.generateCSRFToken();
      }
      
      // Layer 1: Input Validation
      validateInput(input, rules) {
        const errors = [];
        
        if (rules.required && !input) {
          errors.push('Field is required');
        }
        if (rules.maxLength && input.length > rules.maxLength) {
          errors.push(`Max length is ${rules.maxLength}`);
        }
        if (rules.pattern && !rules.pattern.test(input)) {
          errors.push
    ...

    Security Best Practices Checklist

    Security Best Practices

    Complete security checklist and audit tools

    Try it Yourself »
    JavaScript
    // Security Best Practices Checklist
    
    const securityChecklist = {
      // XSS Prevention
      xss: {
        "Use textContent instead of innerHTML": true,
        "Escape HTML entities": true,
        "Use DOMPurify for HTML sanitization": true,
        "Validate URL protocols": true,
        "Never use eval()": true,
        "Implement CSP headers": true
      },
      
      // CSRF Prevention
      csrf: {
        "Use CSRF tokens": true,
        "SameSite cookie attribute": true,
        "Verify Origin header": true,
        "Use POST for state changes
    ...

    🛡️ Security Mastery Summary

    • XSS Prevention: Use textContent, escape HTML, sanitize with DOMPurify
    • CSRF Protection: Use tokens, SameSite cookies, validate Origin headers
    • Input Sanitization: Validate, sanitize, and escape ALL user input
    • Token Security: Use HttpOnly cookies, memory storage, short expiry
    • CSP: Implement strict Content Security Policy headers
    • URL Safety: Validate protocols, prevent open redirects
    • Defense-in-Depth: Layer multiple security mechanisms
    • Never trust: localStorage, URL params, API responses, cookies

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service