myHotTake

Tag: JavaScript security tips

  • How Do You Detect and Prevent DOM-Based XSS Attacks?

    Hey there, if you find this story intriguing or helpful, feel free to give it a like or share it with your fellow tech enthusiasts!


    I’m a researcher in an old library. This library is unlike any other; it’s filled with not just books, but portals that transport me into the stories themselves. Each portal represents a webpage, and I’m on a quest to uncover the secrets of DOM-based XSS attacks, which are like mischievous imps hiding in the pages.

    As I wander through the library, I realize that these imps don’t come from outside the library; instead, they’re sneakily embedded within the pages of the books themselves, waiting for an unsuspecting reader to activate them. I need to be vigilant to detect these imps before they cause chaos. I begin by carefully examining each portal’s frame. If I notice any text that seems out of place or too eager to escape the page, I know I’ve found an imp.

    To prevent them from wreaking havoc, I decide to fortify the portals. I start by ensuring that the library’s quills—akin to JavaScript functions—are sanitized. This means I’m scrubbing them clean of any impish influence before they interact with the portals. I avoid directly inserting any untrusted text I find into the portals, preferring instead to pass it through a rigorous cleansing process.

    Next, I enchant the portals with spells that limit their power, known as Content Security Policies. These spells restrict the imps’ ability to summon external resources, thus keeping them contained within the pages they inhabit.

    Finally, I employ a mystical barrier called a Trusted Types policy. This powerful enchantment ensures that only authorized quills can craft the links within the portals, effectively barring any imp from weaving its own mischief.


    In the world of JavaScript, these imps often exploit the Document Object Model (DOM) by using unsafe methods to insert untrusted data into the pages. To illustrate, let’s look at a common scenario: dynamically updating the content of a page using JavaScript.

    // Unsafe way that might invite imps
    let userInput = "<img src='x' onerror='alert(1)'>";
    document.getElementById("output").innerHTML = userInput;

    Here, I’ve inadvertently invited an imp by directly inserting user input into the page’s HTML. To detect this, I’d be wary of any code that mixes user input with DOM manipulation functions like innerHTML, document.write(), or eval().

    To prevent the imp from causing trouble, I adopt safer practices:

    1. Sanitization and Encoding:
      I ensure the input is sanitized or encoded, so it cannot execute harmful scripts.
    // Using textContent for safer insertion
    let safeOutput = document.createElement('div');
    safeOutput.textContent = userInput;
    document.getElementById("output").appendChild(safeOutput);
    1. Content Security Policy (CSP):
      I set up a CSP to restrict the types of resources that can be loaded. This acts like a barrier, allowing only trusted scripts to run.
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    1. Trusted Types:
      By using Trusted Types, I ensure that the only code allowed to interact with the DOM is pre-approved, keeping the imps at bay.
    // Example setup for Trusted Types
    if (window.trustedTypes) {
      const policy = trustedTypes.createPolicy('default', {
        createHTML: (string) => string
      });
    }

    Key Takeaways:

    • Detection: Always be suspicious of any code that directly manipulates the DOM with untrusted data. Review your use of methods like innerHTML and eval().
    • Prevention:
    • Use safer methods like textContent and createElement.
    • Implement Content Security Policies to restrict script execution.
    • Leverage Trusted Types to control which scripts can write to the DOM.