A Recipe for Scaling Security
This talk demonstrates techniques for mitigating Cross-Site Scripting (XSS) vulnerabilities at scale within large web applications. It focuses on implementing Content Security Policy (CSP) and Trusted Types to enforce security at the browser level. The speakers provide a practical approach to refactoring codebases to use these defenses, emphasizing the importance of secure-by-default frameworks. The presentation also introduces tools for static analysis and automated refactoring to assist developers in adopting these security measures.
Beyond CSP: Why Trusted Types Are the Real Fix for DOM-based XSS
TLDR: DOM-based XSS remains a persistent threat because modern frameworks often rely on dangerous sink APIs that developers inadvertently misuse. While Content Security Policy (CSP) provides a baseline, it is often misconfigured or bypassed, making it insufficient for complex applications. This post explores how implementing Trusted Types forces browsers to reject unsafe string assignments, effectively neutralizing DOM-XSS at the runtime level.
Cross-Site Scripting (XSS) is far from a solved problem. Despite the industry shift toward modern frontend frameworks like React, Angular, and Lit, the underlying issue of mixing user-controlled input with executable code remains. The attack surface for DOM-based XSS is massive, involving over 60 distinct JavaScript APIs that can turn strings into executable code. When a developer uses an API like innerHTML or document.write with unsanitized input, they create a direct path for an attacker to execute arbitrary code in the victim's browser.
The industry has long relied on Content Security Policy (CSP) to mitigate these risks. However, CSP is a blunt instrument. It is notoriously difficult to configure correctly at scale, and it often fails to account for the nuances of complex, single-page applications. A CSP that is loose enough to not break your application is often loose enough to be bypassed by a clever attacker. The real solution requires moving away from policy-based detection toward runtime enforcement.
The Problem with String-Based Sinks
At the heart of DOM-based XSS is the browser's willingness to interpret strings as code. When you pass a string to a sink like element.innerHTML, the browser does not know if that string came from a trusted template or a malicious URL parameter. It simply executes what it is given.
Consider a simple, vulnerable implementation:
var userControlledInput = location.hash.slice(1);
document.getElementById('content').innerHTML = userControlledInput;
In this scenario, location.hash is a user-controlled string. If an attacker sets the hash to <img src=x onerror=alert(1)>, the browser will execute the script. While modern frameworks abstract away some of this manual DOM manipulation, developers still frequently drop down to these dangerous APIs when they need to perform complex rendering or integrate third-party libraries. Once a dangerous sink is used, the framework's built-in protections are often bypassed.
Enforcing Security with Trusted Types
Trusted Types changes the game by requiring that all dangerous sinks receive a "Trusted Type" object instead of a plain string. If you attempt to pass a string to a sink like innerHTML while Trusted Types is enforced, the browser will throw a runtime error and block the execution.
To implement this, you define a policy that governs how strings are converted into trusted objects:
const policy = trustedTypes.createPolicy('default', {
createHTML: (input) => sanitize(input)
});
element.innerHTML = policy.createHTML(userControlledInput);
By enforcing this policy, you move the security decision from the point of execution to the point of creation. You are essentially telling the browser: "Only accept HTML that has been processed by this specific, audited function." This approach is significantly more robust than a CSP because it is enforced by the browser's internal type system, not just by a header that can be ignored or misconfigured.
Scaling Security in Large Codebases
For a pentester or bug bounty hunter, the most interesting aspect of this research is how it scales. Implementing Trusted Types across a massive, legacy codebase is a daunting task. The Trusted Types API allows for a "report-only" mode, which is essential for identifying where your application is currently violating these rules without breaking production traffic.
During an engagement, you should look for applications that have implemented a CSP with the require-trusted-types-for 'script' directive. This is a strong indicator that the development team is actively working to eliminate DOM-XSS. If you find an application that is not using this, you have a clear path to demonstrate the impact of DOM-based XSS by showing how easily these sinks can be reached through multiple levels of indirection or third-party dependencies.
The OWASP DOM-based XSS Prevention Cheat Sheet provides an excellent breakdown of the sinks you should be targeting during your reconnaissance. When you find a sink that is not protected by a Trusted Types policy, you are looking at a potential vulnerability.
The Future of Secure Development
The shift toward "secure-by-default" frameworks is the only way to win the war against XSS. We are seeing a move toward tools that perform static analysis to catch these issues during the build process. Projects like Safety Web are leading the way by providing libraries that steer developers toward safe alternatives before the code ever reaches the browser.
If you are a researcher, start looking for applications that are using these modern defenses. The goal is no longer just to find an XSS, but to understand how these new browser-level protections can be bypassed or misconfigured. The next generation of bug bounty reports will focus on the gaps in these policies, not just the presence of a vulnerable sink. Keep an eye on the CSP Evaluator to test your findings and see how your target's security posture holds up against these modern enforcement mechanisms. The era of simple, string-based XSS is ending, and it is time to start thinking about how we can break the next layer of browser security.
Vulnerability Classes
Target Technologies
Attack Techniques
OWASP Categories
Up Next From This Conference

Breaking Secure Web Gateways for Fun and Profit

Listen to the Whispers: Web Timing Attacks That Actually Work

Abusing Windows Hello Without a Severed Hand
Similar Talks

Kill List: Hacking an Assassination Site on the Dark Web

Living off Microsoft Copilot

